Memory leak

May 20, 2014 at 9:10 AM
Edited May 20, 2014 at 9:37 AM
Hi,

I think there is memory leak when I set script variable via dynamic Script property.
GC cannot collect the TestClass class. In following code I added my class and removed it from scripter.
class Program
{
    static void Main(string[] args)
    {
        var scriptEngine = new VBScriptEngine();                    
        
        scriptEngine.Script.obj = new TestClass();
        scriptEngine.Script.obj = null;
        //scriptEngine.AddHostObject("obj",  new TestComClass());
        scriptEngine.Dispose();
        scriptEngine = null;

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        Console.WriteLine(TestComClass.CollectedByGC);
        Console.ReadKey();
    }
}

public class TestClass
{
    public static bool CollectedByGC { get; set; }
    public TestClass()
    {
        Console.WriteLine("TestClass is created");
        CollectedByGC = false;
    }

    ~TestClass()
    {
        Console.WriteLine("TestClass is collected");
        CollectedByGC = true;
    }
}
I used with .NET memory profiler for understanding where is memory leak and have following instance graph. As we can see HostItem hold TestCalss and refcounted to native object.

Image
https://www.dropbox.com/s/smem5yv7xup4fts/clearscript.jpg
Coordinator
May 20, 2014 at 4:57 PM
Confirmed; the issue affects the Windows script engines (JScript/VBScript). Thanks for reporting it. We're investigating.
Coordinator
May 21, 2014 at 3:58 PM
We're tracking this issue here. Thanks again!
May 21, 2014 at 4:20 PM
Edited May 21, 2014 at 4:28 PM
If I understand correctly you don't have quick fix for this issue
I have delphi legacy application that deal with windows script engine and have similar to setProperty functions and I did not heared about memory leaks.
Delphi code call Invoke function of IDispatch interface with parameter DISPATCH_PROPERTYPUTREF.
That should be similar to following VBScript statement : set name1 = Nothing;
If you interesting I can send to your email delphi code.
Coordinator
May 22, 2014 at 1:56 PM
Hi ifle,

After further investigation it does look like the bug is not in JScript/VBScript. That's good news because patching those components would be difficult if not impossible.

There are many ways for .NET code to interface with COM components. To manipulate script objects, ClearScript originally used .NET's dynamic infrastructure, but over time several bugs were found, so we changed some of the code paths to leverage IExpando-over-IDispatchEx (for lack of a better term). This fixed the bugs but apparently introduced the interface leak you've discovered.

In our investigation we found that going back to using the dynamic infrastructure fixes the interface leak but reintroduces the old bugs. So no, we don't have a quick fix, but we're still investigating, and there are lots of potential solutions to explore.

Stay tuned!
May 22, 2014 at 4:43 PM
Edited May 22, 2014 at 4:46 PM
I understand.
Can you give me small example how via a dynamic infrastructure free an interface?
I have modificated version of ClearScript, similar to our legacy application and this is fix may will be well for me.

Thanks
Coordinator
May 24, 2014 at 3:53 PM
Unfortunately we don't have a simple patch for this issue at this time.

It looks increasingly like the problem may be in the .NET framework, specifically in the IExpando-over-IDispatch functionality provided by COM Interop. Older versions of ClearScript didn't use this facility and didn't have this issue.

In any case, we're already working on a fix in ClearScript. Please stay tuned.
May 24, 2014 at 7:47 PM
Thanks a lot. I will wait to your solution.
Coordinator
Jun 1, 2014 at 1:19 PM
Hello ifle,

The fix is now available.

Thanks again!
Jun 1, 2014 at 5:17 PM
Perfect! I will try it. Thanks.
Jun 3, 2014 at 12:02 PM
I tried your fix and all works as expected. Great work. Thanks again.
Coordinator
Jun 3, 2014 at 5:15 PM
Thanks for verifying the fix, and thanks again for reporting this issue!