1

我正在开发的一个应用程序嵌入了V8以进行脚本编写。为了节省内存,我想在不需要时关闭脚本组件,但由于某种原因,内存永远不会返回给操作系统。

这是我尝试过的:

1. 在持久上下文句柄上调用 Dispose()

context.Dispose();

2.强制垃圾回收

while (!v8::V8::IdleNotification());

这些都对进程内存使用没有任何显着影响。当脚本要求内存时,我可以清楚地看到它是如何上升的,但它再也不会下降了。

我正在确定进程内存使用情况ps -o rss。我知道如果没有分析器,就无法确定一个进程正在使用多少内存,但我确实相信当 V8 释放内存时 rss 应该会下降。

4

2 回答 2

0

只是花了几个小时来解决这个问题,最终不得不深入研究 V8 的 api.cc。

结果是 V8 将全局对象模板的最后一个实例固定为快速重用(无论是原始 ObjectTemplate 还是从 FunctionTemplate 派生的代理)。在尝试强制 GC 刷新时,这非常令人困惑。解决方法是分配新的虚拟上下文(使用与您尝试刷新的上下文相同的模板)。

static void do_gc()
{
  {
    Isolate *i = Isolate::GetCurrent();
    HandleScope h(i);
    Handle<Context> c = Context::New(i); // Default contexes
    Handle<Context> c = Context::New(i, 0, objtemplate); // With custom object
    Handle<Context> c = Context::New(i, 0, fntemplate->InstanceTemplate()); // With proxy
  }
  while (!v8::V8::IdleNotification());
}

在上下文中查看用法https://github.com/katlogic/lv8/blob/344353dac702901c917a4c05438252121c527ab3/lv8.cpp#L755

于 2014-05-03T04:21:14.313 回答
0

即使您的应用程序已正确释放内存,操作系统也可能根本没有回收内存(例如出于性能原因)。应用程序堆也可能持有内存,以防您很快再次需要它。无论哪种方式,如果你确定你没有泄漏(尝试类似 valgrind),我不会担心它。

于 2013-03-08T13:05:30.510 回答