V8的垃圾回收似乎很容易清理,因为它达到Local<T>
值,其中T
存储在Local
中,但是如果创建ObjectTemplate
然后创建该Object
的实例,v8将等待清理内存。考虑下面的示例,其中居民集大小在整个程序执行期间保持稳定:
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();
}
上面,我们要做的是在一个循环中创建一个新的Object
,然后handle_scope
超出范围,看起来分配的Local
值立即被垃圾回收,因为住宅规模保持稳定。但是,通过同时在循环中创建的ObjectTemplate
创建该对象时会出现问题:
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();
}
在这里,驻留集的大小线性增加,直到对于这样一个小的程序使用了不必要的ram。只是想了解这里发生了什么。很抱歉,冗长的解释,我试图将其简短化,以至于:p。提前致谢!
答案 0 :(得分:0)
V8假定ObjectTemplates寿命很长,因此将它们分配在堆的“老一代”部分中,在那里(相对较慢且很少见)完整的GC周期收集它们会花费更长的时间-如果假设是正确的,并且它们实际上是长期存在的,这是整体表现的胜利。另一方面,对象本身是在“年轻一代”中分配的,通过(相对频繁的)年轻一代GC周期可以快速,轻松地收集对象。
如果使用--trace-gc运行,则应确认此说明。