I'm having a problem where I can't get an object passed to javascript to be garbage collected.
I've included sample code below.
It demonstrates that calling JavascriptContext.Collect and GC.Collect can not clean up the reference to HeavyObject.
Besides the WeakReference indication you can open task manager and see that before you press a key for the first time it uses 100 megs of memory.
Once you press a key the JavascriptContext is disposed, the WeakReference reports that the object is dead, and task manager shows the memory usage dropped to a couple of megs.
Am I doing something wrong here? Or is there no way to clean up objects that were passed to noesis.javascript.net without disposing the entire context?
using System;
using Noesis.Javascript;
namespace NoesisMemoryLeakTest
{
I've included sample code below.
It demonstrates that calling JavascriptContext.Collect and GC.Collect can not clean up the reference to HeavyObject.
Besides the WeakReference indication you can open task manager and see that before you press a key for the first time it uses 100 megs of memory.
Once you press a key the JavascriptContext is disposed, the WeakReference reports that the object is dead, and task manager shows the memory usage dropped to a couple of megs.
Am I doing something wrong here? Or is there no way to clean up objects that were passed to noesis.javascript.net without disposing the entire context?
using System;
using Noesis.Javascript;
namespace NoesisMemoryLeakTest
{
class Program
{
static void Main(string[] args)
{
WeakReference wr;
using (var js = new JavascriptContext())
{
wr = AddHeavyInScopedMethod(js);
JavascriptContext.Collect();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// and again just in case the order the collections happened matters
JavascriptContext.Collect();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
Console.WriteLine(wr.IsAlive); // prints true
Console.ReadKey();
} // end using javascript context
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
Console.WriteLine(wr.IsAlive); // prints false
Console.ReadKey();
}
static WeakReference AddHeavyInScopedMethod(JavascriptContext js)
{ // by adding the heavy object here and returning a WeakReference we ensure that C# holds no strong references to the HeavyObject
var heavy = new HeavyObject();
var wr = new WeakReference(heavy);
js.SetParameter("heavy", heavy);
js.Run("heavy = null;");
return wr;
}
} // end Program class
public class HeavyObject
{
const int ArraySize = 100000000;
public byte[] Buffer = new byte[ArraySize];
// constructor
public HeavyObject()
{
for (int i=0; i < ArraySize; i++)
Buffer[i] = (byte)(i % 256);
}
} // end HeavyObject class
}