如何释放V8所占用的内存

How to free up the memory claimed by V8?

本文关键字:内存 V8 何释放 释放      更新时间:2023-10-16

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

这是我尝试的:

1。对持久上下文句柄

调用Dispose()
context.Dispose();

2。强制垃圾回收

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

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

我正在确定ps -o rss的进程内存使用情况。我知道,如果没有分析器,要计算出进程使用了多少内存是不可能的,但我确实认为,当V8释放内存时,rss应该下降。

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

我花了几个小时来解决这个问题,最终不得不深入研究api。

结果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