Reputation: 85
V8's garbage collection seems to easily clean up as it goes a Local<T>
value where T
anything stored in the Local
, however if you create an ObjectTemplate
and then create an instance of that Object
, v8 will wait to clean up the memory. Consider the following example where the resident set size remains stable throughout program execution:
Isolate* isolate = Isolate::New(create_params);
Persistent<Context> *context= ContextNew(isolate); // creates a persistent context
for(int i = 1 ; i <= 1000000; i ++ ) {
isolate->Enter();
EnterContext(isolate, context); // enters the context
{
HandleScope handle_scope(isolate);
Local<Object> result = Object::New(isolate);
}
ExitContext(isolate, context);
isolate->Exit();
}
Above, all we do is create a new Object
in a loop, and then handle_scope
goes out of scope and it looks like the Local
values allocated are garbage collected right away as the residential set size remains steady. However, there is an issue when this object is created through an ObjectTemplate
that is also created in the loop:
Isolate* isolate = Isolate::New(create_params);
Persistent<Context> *context= ContextNew(isolate); // creates a persistent context
for(int i = 1 ; i <= 1000000; i ++ ) {
isolate->Enter();
EnterContext(isolate, context); // enters the context
{
HandleScope handle_scope(isolate);
Local<Object> result;
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
if (!templ->NewInstance(context->Get(isolate)).ToLocal(&result)) { exit(1); }
}
ExitContext(isolate, context);
isolate->Exit();
}
Here, the resident set size increases linearly until an unnecessary amount of ram is used for such a small program. Just looking to understand what is happening here. Sorry for the long explanation, i tried to keep it short and to the point :p. Thanks in advance!
Upvotes: 0
Views: 127
Reputation: 40561
V8 assumes that ObjectTemplates are long-lived and hence allocates them in the "old generation" part of the heap, where it takes longer for them to get collected by a (comparatively slow and rare) full GC cycle -- if the assumption was right and they actually are long-lived, this is an overall performance win. Objects themselves, on the other hand, are allocated in the "young generation", where they are quick and easy to collect by the (comparatively frequent) young-generation GC cycles.
If you run with --trace-gc you should see this explanation confirmed.
Upvotes: 1