Quantcast
Channel: ClearScript
Viewing all articles
Browse latest Browse all 2297

New Post: memory leak when passing javascript object to managed code

$
0
0
Hi Tom,

Unfortunately memory management can get tricky with long-running scripts.

When you pass a script object into managed code, ClearScript creates a managed proxy for it. The proxy holds a strong reference to its target, so the script object can't be garbage-collected until the proxy is disposed or finalized.

Therefore one way to avoid the leak is to dispose the proxy when you're done with it:
publicvoid doSomething(dynamic foo) {
    var disposable = foo as IDisposable;
    if (disposable != null) {
        disposable.Dispose();
    }
}
Another possibility is to invoke managed garbage collection and finalization before calling ScriptEngine.CollectGarbage():
publicvoid garbageCollect() {
    GC.Collect();
    GC.WaitForPendingFinalizers();
    // [...]
    m_engine.CollectGarbage(true);
    // [...]
}
An unfortunate wrinkle with this approach is that you can no longer call garbageCollect() from script code. Proxy finalization requires help from the script engine, which is locked during script execution, so the GC.WaitForPendingFinalizers() call causes a deadlock. Instead, you'll have to restructure your code like this:
engine.Execute(@"var count = 0");
while (true) {
    engine.Execute(@"
        while (true) {
            if (++count % 10000 == 0) {
                break;
            }
            obj = {
                a: ""b"",
                c: ""d""
            };
            nativeBridge.doSomething(obj);
        }
    ");
    p.garbageCollect();
}
Thanks, and good luck!

Viewing all articles
Browse latest Browse all 2297

Trending Articles