ClearScript: Hard crash if out of memory
First, thank you for this project. We use it extensively to do server-side rendering of our React application and it works really well.
One issue we have encountered (which I don’t if it is possible to fix) is that when we had a memory leak, we would eventually get a hard process crash with this call stack:
Application: w3wp.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
at <Module>.std._Func_class<void>.()()(std._Func_class<void>*)
at Microsoft.ClearScript.V8.NativeCallbackImpl.Invoke()
at Microsoft.ClearScript.Util.MiscHelpers.Try(System.Action)
at Microsoft.ClearScript.Util.MiscHelpers+<>c__DisplayClass23_0.<QueueNativeCallback>b__0(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
The error can be triggered by this code:
var runtime = new V8Runtime();
var engine = runtime.CreateScriptEngine(V8ScriptEngineFlags.DisableGlobalMembers);
engine.AllowReflection = false;
engine.EnableAutoHostVariables = false;
engine.UseReflectionBindFallback = false;
engine.DefaultAccess = ScriptAccess.None;
engine.Execute("var leak = [];");
for (;;)
{
engine.Execute("(function() {const x = []; for (let i = 0; i < 10000; i++) x[i] = Math.random(); leak.push(x);})();");
}
I am aware that my code needs to be fixed and that a crash is inevitable, but I would prefer if the crash happened in some other way than an access violation (which I guess is due to an allocation return value not being checked somewhere) that tears down my entire process without the possibility of preventing it.
Preferrably I would eventually get an exception in the Execute()
call (which could or could not require that the engine be disposed of afterwards).
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 23
Hi @erik-kallen,
That’s not correct. V8 releases unused committed memory during exhaustive garbage collection. Here’s how you can verify that:
Yes. Setting
MaxOldSpaceSize
significantly higher thanMaxHeapSize
is critical, as it makes monitoring much more likely to terminate script execution before V8 kills the process.No. That doesn’t seem to have much effect in recent V8 versions, whereas careful setting of
MaxOldSpaceSize
andMax[Runtime]HeapSize
can prevent most hard crashes.V8 does allow the host to set up an OOM callback (for logging purposes only; it’ll kill the process as soon as the callback returns), but ClearScript doesn’t expose this. Of course, if you use the techniques discussed here, you can catch OOM before it kills the process and log anything you wish.
Cheers!