V8垃圾收集对使用它们创建的对象模板和对象的不同

时间:2019-06-12 17:16:08

标签: v8 embedded-v8

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。提前致谢!

1 个答案:

答案 0 :(得分:0)

V8假定ObjectTemplates寿命很长,因此将它们分配在堆的“老一代”部分中,在那里(相对较慢且很少见)完整的GC周期收集它们会花费更长的时间-如果假设是正确的,并且它们实际上是长期存在的,这是整体表现的胜利。另一方面,对象本身是在“年轻一代”中分配的,通​​过(相对频繁的)年轻一代GC周期可以快速,轻松地收集对象。

如果使用--trace-gc运行,则应确认此说明。