【问题标题】:How to free up the memory claimed by V8?如何释放 V8 占用的内存?
【发布时间】:2013-02-23 22:34:16
【问题描述】:

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

这是我尝试过的:

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

context.Dispose();

2。强制垃圾回收

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

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

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

【问题讨论】:

  • 哎哟。得调查一下。如果有人用 V8 解决了这个问题,我仍然会感兴趣 - 我能想到的唯一解决方案是将 v8 加载到一个分叉的进程中并杀死那个。
  • 是的,这确实发生在一个简单的 C 程序中 :( 仍然希望有关如何让操作系统回收内存的建议。
  • 我建议你也需要销毁你的IsolateContext 执行的 V8 实例),如果 Isolate 是 'Enter()由您的Context编辑

标签: c++ memory embed v8 embedded-v8


【解决方案1】:

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

【讨论】:

  • 对此进行了一些实验,但感觉很神秘。如果我在一个小 C 程序中分配 100 MB 的内存,那么在程序退出之前,内存永远不会被回收。如果我改为分配 500 MB,它几乎会立即被回收。知道我是否可以强制操作系统回收它吗?
  • 我猜在你的实验中你越过了操作系统和/或应用程序堆库“决定”它有足够的内存来保证将它返回到系统池的某个阈值。我不知道影响这些决定的标准方法......这是一种实施权衡。例如,如果您继续循环分配和释放 100MB 会怎样?
【解决方案2】:

只是花了几个小时来解决这个问题,最终不得不深入研究 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的用法

【讨论】:

    猜你喜欢
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多