v8 Context memory leaks

262 views
Skip to first unread message

Juggle

unread,
Jul 8, 2015, 11:30:35 AM7/8/15
to v8-u...@googlegroups.com
Hi.

I'm trying to develop nodejs module on C++ using v8.

Here is source code.

    #include <node.h>


   
using namespace v8;


   
void TestContext1(const FunctionCallbackInfo<Value>& args) {


       
Isolate* isolate = Isolate::New();
       
{
           
Isolate::Scope isolate_scope(isolate);
            V8
::Initialize();
           
Locker lock(isolate);


           
HandleScope handle_scope(isolate);


           
Local<Context> context = Context::New(isolate);
           
Context::Scope context_scope(context);




           
Handle<String> strExpr = Handle<String>::Cast(args[0]);
           
Handle<Script> script;
           
Handle<Value> res;


           
TryCatch tryCatch;
            script
= Script::Compile(strExpr);
            res
= script->Run();


           
if (tryCatch.HasCaught()) {
                res
= tryCatch.Message()->Get();
           
}


            args
.GetReturnValue().Set(res);
       
}
        isolate
->Dispose();


   
}




   
void TestContext2(const FunctionCallbackInfo<Value>& args) {


       
Isolate *isolate = args.GetIsolate();
       
Isolate::Scope isolate_scope(isolate);
       
HandleScope handle_scope(isolate);
       
Local<Context> context = Context::New(isolate);
       
Context::Scope context_scope(context);


       
Handle<String> strExpr = Handle<String>::Cast(args[0]);
       
Handle<Script> script;
       
Handle<Value> res;


       
TryCatch tryCatch;
        script
= Script::Compile(strExpr);
        res
= script->Run();


       
if (tryCatch.HasCaught()) {
            res
= tryCatch.Message()->Get();
       
}


        args
.GetReturnValue().Set(res);
   
}


   
void Init(Handle<Object> exports, Handle<Object> module) {
        NODE_SET_METHOD
(exports, "TestContext1", TestContext1);
        NODE_SET_METHOD
(exports, "TestContext2", TestContext2);
   
}


    NODE_MODULE
(addon, Init)


And then testing it with js code:

    var addon = require('addon.node')
   
var i = 0;
    setInterval
(function () {
        msg
= addon.TestContext1("process.exit()"); // or msg = addon.TestContext2("process.exit()");
        console
.log(msg, i++, process.memoryUsage().heapUsed/1024/1024);
   
}, 2);


Every function have different problems:

**TestContext1** works fine but accessing global context and shutting down process.

**TestContext2** does not have access to global context but gives memory leaks.

All what I need - execute js script in isolated context without memory leaks.

node vm doesn't work because vm.runInNewContext() have same memory leaks. 

Does anybody have some ideas?

Ben Noordhuis

unread,
Jul 8, 2015, 4:48:21 PM7/8/15
to v8-u...@googlegroups.com
Sample 1 is unsafe because you're passing a value from one isolate to
another. Don't do that, it won't work.

Sample 2 may benefit from calling
isolate->ContextDisposedNotification() and, possibly,
isolate->LowMemoryNotification(), but it won't help when complex
values like arrays and objects from the temporary context escape to
the main context. JS objects retain references to things like their
constructors and prototypes, which in turn retain references to their
constructors and prototypes, etc. You quickly end up retaining most
of the context.
Message has been deleted

Ben Noordhuis

unread,
Jul 8, 2015, 5:33:49 PM7/8/15
to v8-u...@googlegroups.com
On Wed, Jul 8, 2015 at 11:09 PM, Juggle <a.isr...@gmail.com> wrote:
> Hi Ben.
>
> Thank you for your responding.
>
> I see about Sample 1.
> But what about Sample 2? There is memory leaks when I use this test code:
>
> setInterval(function () {
> msg = addon.TestContext2("1==1");
> console.log(msg, i++, process.memoryUsage().heapTotal/1024/1024);
> }, 2);

Does the process run out of memory if you run it for long enough? Do
the isolate->ContextDisposedNotification() and
isolate->LowMemoryNotification() hints help? Make sure you call them
when the Context::Scope object is no longer in scope.
Reply all
Reply to author
Forward
0 new messages