C# 重复初始化Clearscript V8引擎时内存不足(GC问题?)

C# 重复初始化Clearscript V8引擎时内存不足(GC问题?),c#,asp.net,memory-leaks,garbage-collection,v8,C#,Asp.net,Memory Leaks,Garbage Collection,V8,我已经创建了一个基本的默认ASP.NET 5项目。我有一个控制器,可以创建 var engine = new V8ScriptEngine(); 并返回一些模拟json。当我刷新页面时,会得到一定的次数 堆设置中出现致命错误 分配失败-进程内存不足 并跟踪堆栈跟踪 Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invo

我已经创建了一个基本的默认ASP.NET 5项目。我有一个控制器,可以创建

var engine = new V8ScriptEngine();
并返回一些模拟json。当我刷新页面时,会得到一定的次数

堆设置中出现致命错误

分配失败-进程内存不足

并跟踪堆栈跟踪

Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at V8Isolate.Create(StdString* , V8IsolateConstraints* , Boolean , Int32 )
   at Microsoft.ClearScript.V8.V8IsolateProxyImpl..ctor(String gcName, V8RuntimeConstraints gcConstraints, Boolean enableDebugging, Int32 debugPort)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, Object[] args)
   at Microsoft.ClearScript.V8.V8Proxy.CreateImpl[T](Object[] args)
   at Microsoft.ClearScript.V8.V8IsolateProxy.Create(String name, V8RuntimeConstraints constraints, Boolean enableDebugging, Int32 debugPort)
   at Microsoft.ClearScript.V8.V8Runtime..ctor(String name, V8RuntimeConstraints constraints, V8RuntimeFlags flags, Int32 debugPort)
   at Microsoft.ClearScript.V8.V8ScriptEngine..ctor(V8Runtime runtime, String name, V8RuntimeConstraints constraints, V8ScriptEngineFlags flags, Int32 debugPort)
   at Microsoft.ClearScript.V8.V8ScriptEngine..ctor()
我试图用
dotMemory
查看内存。每次我刷新页面时,都会创建一个引擎,并向非托管内存添加2MB的ram。当它达到一定的极限时,它就会崩溃,如上所述。只要我在达到限制之前单击forcegc,内存就会下降,我就可以再次使用该页面

我的问题是:为什么GC不首先处理这个问题?在每次请求之后,如果我强制GC,对象可以被释放。我会告诉你,如果我几乎没有内存,但我可以用GC回收它,它就会这样做

我如何解决这个问题?也许增加更多的内存会有帮助,但我也不知道怎么做。如果GC永远不会清理这些对象,它无论如何都会崩溃

当我运行Kestrel(
DNXWeb
)和使用
IIS
时也会发生同样的情况。 我已将框架设置为“dnx46”

这是我的dnx版本

$ dnx --version
Microsoft .NET Execution environment
 Version:      1.0.0-rc1-16231
 Type:         Clr
 Architecture: x86
 OS Name:      Windows
 OS Version:   10.0
 Runtime Id:   win10-x86

ClearScript版本是“ClearScript.V8”:“5.4.3”

简短版本:使用完每个脚本引擎后,需要对其进行更新。一种方便的方法是使用以下语句:

using (var engine = new V8ScriptEngine()) {
    // do stuff
}

更长的版本:每个V8实例保留一大块地址空间。这些不会显示为已用内存,但在32位进程中,只有几十个实例会耗尽地址空间。托管GC最终会将其清理干净,但因为它无法跟踪V8的地址空间保留,所以它并不急于这样做,因为它没有检测到任何内存压力。最终,您的内存使用率仍然很低,但V8无法再保留足够大的地址空间块,因此它失败了。

您是在使用之后将对它的所有引用都置空,还是等待它决定生命的结束?我没有将其置空,但它超出了范围:
[HttpGet]public JsonResult get(){var engine=new V8ScriptEngine();返回新的JsonResult(“asd”);}
我有一些问题,让事情滑入范围外是不够的-我有excel,即使你说退出,它也会让它打开..我有很多事情,将它们置零总是解决问题。如果我有一个类在内部创建引擎,我应该在中实现
IDisposable
它并委托给引擎的
Dispose
方法,并在我完成时显式调用它,或者使用
using
construct,对吗?是的;为了获得最佳效果,如果您的类在内部使用
V8ScriptEngine
,它应该实现
IDisposable
并委托实现。