Hi,
While investigating some memory related issues in my application, I managed to reproduce what seems to be a problem. The following minimal application terminates on my PC after ~50 cycles and prints the following to console:
```
#
# Fatal error in heap setup
# Allocation failed - process out of memory
#
```
```
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000; i++)
{
using (V8ScriptEngine engine = new V8ScriptEngine())
{
Console.WriteLine("Created engine #{0}", i);
engine.Execute("function zz(){}");
var tmp = engine.Evaluate("zz");
}
}
}
}
```
Strangely, the memory usage doesn't seem high when it terminates.
I used both a Nuget package, and a manually built latest ClearScript + V8 with same results.
Any help will be greatly appreciated.
Thanks in advance again,
Ron
Comments: Hi Ron, First, we agree that there's a problem here. Script objects are not usable after the engine is disposed, so there's no reason for them to keep the V8 runtime alive beyond that point. We're working on a fix, and we'll use this issue to track it. Now, to answer your questions: >I think that in a realistic scenario it would not always be possible to dispose the script object at that time. Yes, it can be inconvenient, but again, in most situations it isn't necessary, as the managed garbage collector eventually takes care of it. In server scenarios we recommend using a fixed-capacity pool of V8 runtimes - an approach that avoids this issue and should yield the best performance. Also, server processes are usually 64-bit, so address space exhaustion is not a concern for them. >You wrote that "V8 reserves a large block of address space for each one" but I'm creating a new engine each time. At the end of each loop iteration the V8 runtime is being held by both the engine and the script object, so both must be disposed or finalized for the V8 runtime to be destroyed. You were disposing only the engine, so with multiple iterations the V8 runtimes piled up, and the managed garbage collector never got a chance to finalize the script objects before your process ran out of address space. >I verified that I can create more than 50 script items per engine, so where exactly is this ~50 limit? The large address space reservation is per V8 runtime, not per script object. Each V8 runtime reserves at least 16MB of address space at a 32MB boundary, so the theoretical maximum number of concurrent V8 runtimes in a 32-bit Windows process is 64. The real maximum of course is lower than that and depends on the application's memory usage. Thanks again for reporting this issue!
While investigating some memory related issues in my application, I managed to reproduce what seems to be a problem. The following minimal application terminates on my PC after ~50 cycles and prints the following to console:
```
#
# Fatal error in heap setup
# Allocation failed - process out of memory
#
```
```
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000; i++)
{
using (V8ScriptEngine engine = new V8ScriptEngine())
{
Console.WriteLine("Created engine #{0}", i);
engine.Execute("function zz(){}");
var tmp = engine.Evaluate("zz");
}
}
}
}
```
Strangely, the memory usage doesn't seem high when it terminates.
I used both a Nuget package, and a manually built latest ClearScript + V8 with same results.
Any help will be greatly appreciated.
Thanks in advance again,
Ron
Comments: Hi Ron, First, we agree that there's a problem here. Script objects are not usable after the engine is disposed, so there's no reason for them to keep the V8 runtime alive beyond that point. We're working on a fix, and we'll use this issue to track it. Now, to answer your questions: >I think that in a realistic scenario it would not always be possible to dispose the script object at that time. Yes, it can be inconvenient, but again, in most situations it isn't necessary, as the managed garbage collector eventually takes care of it. In server scenarios we recommend using a fixed-capacity pool of V8 runtimes - an approach that avoids this issue and should yield the best performance. Also, server processes are usually 64-bit, so address space exhaustion is not a concern for them. >You wrote that "V8 reserves a large block of address space for each one" but I'm creating a new engine each time. At the end of each loop iteration the V8 runtime is being held by both the engine and the script object, so both must be disposed or finalized for the V8 runtime to be destroyed. You were disposing only the engine, so with multiple iterations the V8 runtimes piled up, and the managed garbage collector never got a chance to finalize the script objects before your process ran out of address space. >I verified that I can create more than 50 script items per engine, so where exactly is this ~50 limit? The large address space reservation is per V8 runtime, not per script object. Each V8 runtime reserves at least 16MB of address space at a 32MB boundary, so the theoretical maximum number of concurrent V8 runtimes in a 32-bit Windows process is 64. The real maximum of course is lower than that and depends on the application's memory usage. Thanks again for reporting this issue!