This project has moved and is read-only. For the latest updates, please go here.

Increasing memory during V8 usage

Aug 8, 2014 at 4:45 PM
Hi,

i have a memory problem and i don't know if it is due to a wrong usage or a problem in the engine.
When I use the V8 engine a long time with many JS-calls from C#:
using (var compiledFunction = m_Engine.Compile(function))
{
    var result = m_Engine.Evaluate(compiledFunction);
    Log.Debug("Result of function '" + function + "': " + result);
}

(also tried: engine.Execute(function);)
and many calls from JS to C# through an object I attached to engine.Script
engine.Script["nameOfObject"] = theObject;

(also tried: engine.AddHostObject("nameOfObject", theObject);)
the memory usage is increasing constantly.
I used DebugDiag2 to see what could cause that problem. Most of the memory is allocated by v8_x64.dll
Module Name   v8_x64 
Allocation Count   466 allocation(s) 
Allocation Size   1.02 GBytes 

---

Function details

Function   v8_x64!v8::Testing::DeoptimizeAll+109ccd 
Source Line    
Allocation type   Virtual memory allocation(s) 
Allocation Count   460 allocation(s) 
Allocation Size   530.3 MBytes 
Leak Probability   84% 
and here is a call stack sample
Call stack sample 3

Address   0x00000000`22000000 
Allocation Time   14:43:09 since tracking started 
Allocation Size   8.02 MBytes 

LeakTrack+229ef    
v8_x64!v8::Testing::DeoptimizeAll+109ccd    
v8_x64!v8::Testing::DeoptimizeAll+c6037    
v8_x64!v8::Testing::DeoptimizeAll+c65b7    
v8_x64!v8::Testing::DeoptimizeAll+c9eb8    
v8_x64!v8::Testing::DeoptimizeAll+248ff    
v8_x64!v8::Testing::DeoptimizeAll+88b5c    
v8_x64!v8::Testing::DeoptimizeAll+52fd8    
v8_x64!v8::Testing::DeoptimizeAll+53324    
v8_x64!v8::Testing::DeoptimizeAll+4ef50    
v8_x64!v8::Testing::DeoptimizeAll+1337c4    
v8_x64!v8::Testing::DeoptimizeAll+133a30    
v8_x64!v8::Testing::DeoptimizeAll+111885    
v8_x64!v8::Script::New+236    
v8_x64!v8::Script::New+31    
ClearScriptV8_64+5a8e    
0x7FE916BF3C1 
Do you see something what I am doing wrong or do you have some hints what else I can try?
Aug 8, 2014 at 9:06 PM
Hello querdenker,

It doesn't look like you're doing anything wrong. Can you say any more about the sort of work your scripts are doing?

Some general suggestions:​
  • Make sure you're using the latest version of ClearScript. A number of memory leaks have been fixed since the last point release.
  • Is it possible that your scripts are generating increasing amounts of data that is reachable from the global/root object?
  • Try to avoid script compilation as much as possible. Consider using compiled scripts or direct invocation of script functions to re-execute script code.
  • We've found that when it comes to garbage collection, V8 is lazy to an extent that can get it in trouble. Consider invoking the garbage collector explicitly via ScriptEngine.CollectGarbage(true). Use a schedule that makes sense for your application - periodically or based on idle state, maximum invocation count, etc.
  • If all else fails, consider disposing the script engine and spinning up a fresh instance once in a while - again, using a schedule that makes sense for you.
Good luck!
Aug 11, 2014 at 9:31 AM
ClearScript wrote:
Hello querdenker,

It doesn't look like you're doing anything wrong. Can you say any more about the sort of work your scripts are doing?

Some general suggestions:​
  • Make sure you're using the latest version of ClearScript. A number of memory leaks have been fixed since the last point release.
I'm using the latest version.
  • Is it possible that your scripts are generating increasing amounts of data that is reachable from the global/root object?
I check this on the scripts I have here to test, but i can't check every script, that is executed by the users.
  • Try to avoid script compilation as much as possible. Consider using compiled scripts or direct invocation of script functions to re-execute script code.
  • We've found that when it comes to garbage collection, V8 is lazy to an extent that can get it in trouble. Consider invoking the garbage collector explicitly via ScriptEngine.CollectGarbage(true). Use a schedule that makes sense for your application - periodically or based on idle state, maximum invocation count, etc.
I had this idea before, but didn't implemted it yet. I give it a try.
  • If all else fails, consider disposing the script engine and spinning up a fresh instance once in a while - again, using a schedule that makes sense for you.
Good luck!
Thanks for your quick response and your hints.
Aug 11, 2014 at 1:46 PM
Hi again,

i can't check every script, that is executed by the users

If you're executing unknown or untrusted scripts, please note that a buggy or malicious script can easily corrupt the environment for subsequent scripts; e.g., by leaving data hanging off the root object, by altering built-in behavior with unexpected extensions, etc. If possible, consider creating a clean context for each script by re-instantiating V8ScriptEngine. If that's too expensive, you might be able to reuse one or more V8 runtimes (see V8Runtime.CreateScriptEngine()).

Cheers!
Aug 11, 2014 at 5:56 PM
ClearScript wrote:
Hi again,

i can't check every script, that is executed by the users

If you're executing unknown or untrusted scripts, please note that a buggy or malicious script can easily corrupt the environment for subsequent scripts; e.g., by leaving data hanging off the root object, by altering built-in behavior with unexpected extensions, etc. If possible, consider creating a clean context for each script by re-instantiating V8ScriptEngine. If that's too expensive, you might be able to reuse one or more V8 runtimes (see V8Runtime.CreateScriptEngine()).

Cheers!
I'm already use such a solution. I have a "Runtime-Pool" (inspired by another thread here ;) ) with a specific number of runtimes and from there I create new V8ScriptEngines for every new script executer, so that I have a defined resource usage, but also a clean environment for every executor.

Now back to my problem. I tried the solution with the schedule of the Garbage Collection and it seems to work. The memory usage looks good now. I will still have a look at it, but I think the problem is resolved ;)

Thanks for your help...