重复初始化 Clearscript V8 引擎时内存不足(GC 问题?)
out of memory when repeatedly initializing Clearscript V8 engine (GC issue?)
我创建了一个基本的默认 ASP.NET 5 项目。我有一个控制器可以创建
var engine = new V8ScriptEngine();
和 returns 一些模拟 json。当我刷新页面一定次数时,我得到
Fatal error in heap setup
Allocation failed - process out of memory
并跟踪堆栈跟踪
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 添加到非托管内存中。当它达到一定的限制时,它会崩溃,如上所述。只要我在达到限制之前单击强制 GC,内存就会下降,我可以再次使用该页面。
我的问题是:为什么 GC 不首先处理这个问题?在每次请求之后,如果我强制 GC 就可以处理该对象。我想如果我几乎没有内存但我可以用 GC 回收它,它会这样做。
我该如何解决这个问题?也许添加更多内存会有所帮助,但我也不知道该怎么做。如果 GC 永远不会清理这些对象,它无论如何都会崩溃。
当我 运行 Kestrel (dnx web
) 和 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"
简短版:您需要dispose each script engine when you're done with it. A convenient way is to use the using
声明:
using (var engine = new V8ScriptEngine()) {
// do stuff
}
更长的版本:每个V8实例保留一大块地址space。这些不会显示为已用内存,但在 32 位进程中,您可以 运行 out of address space 只需几十个实例。托管 GC 最终会将其全部清理干净,但由于它无法跟踪 V8 的地址 space 保留,因此并不急于这样做,因为它没有检测到任何内存压力。最终,您的内存 使用率 仍然很低,但 V8 无法再保留足够大的地址块 space,因此它失败了。
我创建了一个基本的默认 ASP.NET 5 项目。我有一个控制器可以创建
var engine = new V8ScriptEngine();
和 returns 一些模拟 json。当我刷新页面一定次数时,我得到
Fatal error in heap setup
Allocation failed - process out of memory
并跟踪堆栈跟踪
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 添加到非托管内存中。当它达到一定的限制时,它会崩溃,如上所述。只要我在达到限制之前单击强制 GC,内存就会下降,我可以再次使用该页面。
我的问题是:为什么 GC 不首先处理这个问题?在每次请求之后,如果我强制 GC 就可以处理该对象。我想如果我几乎没有内存但我可以用 GC 回收它,它会这样做。
我该如何解决这个问题?也许添加更多内存会有所帮助,但我也不知道该怎么做。如果 GC 永远不会清理这些对象,它无论如何都会崩溃。
当我 运行 Kestrel (dnx web
) 和 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"
简短版:您需要dispose each script engine when you're done with it. A convenient way is to use the using
声明:
using (var engine = new V8ScriptEngine()) {
// do stuff
}
更长的版本:每个V8实例保留一大块地址space。这些不会显示为已用内存,但在 32 位进程中,您可以 运行 out of address space 只需几十个实例。托管 GC 最终会将其全部清理干净,但由于它无法跟踪 V8 的地址 space 保留,因此并不急于这样做,因为它没有检测到任何内存压力。最终,您的内存 使用率 仍然很低,但 V8 无法再保留足够大的地址块 space,因此它失败了。