c++ - 如何判断 v8 isolate 实例使用了太多内存?

标签 c++ v8 embedded-v8

我正在使用 Google 的 v8 引擎在我的应用程序中嵌入 javascript。在某些时候,我会调用用户提供的代码,我想确保它不会因为分配太多内存而表现不佳。例如,当前,当 javascript 尝试使数组过大或将其调整为过大时,我会收到一条粗鲁的消息:

#
# Fatal error in CALL_AND_RETRY_LAST
# Allocation failed - process out of memory
#

然后整个进程因 SIGILL 而崩溃。显然,这是不能接受的。我需要能够运行用户提供的代码,但是......在引擎执行之前手动审查所有代码是不可行的。

在这种情况下,我最理想的做法是简单地终止消耗过多内存的 isolate(而不影响任何其他可能正在运行的 isolate)。有什么方法可以指定 js 程序在失败之前允许使用的最大内存量,因此如果它超过该限制,而不是使进程崩溃,调用 Run 或 Call 命令只会返回错误或者设置一些状态标志,表明它被异常终止。

到目前为止我尝试过的事情:

在创建 isolate 时设置自定义 array_buffer 分配器,它跟踪正在使用的内存量并在内存使用率过高时终止 isolate> 我的分配器的 Allocate 函数从未被调用。

使用跟踪内存使用情况的函数调用 AddMemoryAllocationCallback,并在分配超过一定数量时尝试通过 TerminateExecution() 终止隔离。这个函数确实被调用了,但是在这个函数只报告了几兆字节被使用后我得到了一个内存不足的错误,而我知道一个事实是由行为不佳的 v8 函数创建的数据 FAR 比那个大。

通过 SetFatalErrorHandler 设置 fatal error 处理程序并尝试在那里调用 TerminateExecution。此函数确实会被调用,但它不会阻止进程崩溃。

还有什么我可以尝试的吗?

最佳答案

编辑:V8 团队的权威回应——你不能。但他们会接受补丁。

v8::Isolate::SetFatalErrorHandler() 应该不会崩溃。但是,我的理解是隔离在事后仍然无法使用。可能没有办法解决这个问题,因为隔离物将处于无法恢复的状态。

http://v8.paulfryzel.com/docs/master/classv8_1_1_isolate.html#a131f1e2e6a80618ac3c8c266a041851d

(也许吧。在 2013 年到 2014 年的时间框架内似乎有很多关于此的事情发生,谷歌的人说正确的做法是让 v8 杀死这个过程——很多人都这样做想法是愚蠢的。我没有看到任何解决方案)

编辑:邮件列表回复说你不能这样做。如果补丁没有性能影响,他们将接受补丁。

编辑:关于这个只有另一个线程,有人发布了一个似乎是在非恶意情况下避免 OOM 的好方法:

https://groups.google.com/forum/#!topic/v8-users/vKn1hVs8KNQ

I set the heap limit to 8x the limit I actually want. Then, after each call into the isolate, I check if the memory usage has gone over the intended limit. If so, I invoke garbage collection. If it's still over the limit after that, then I terminate the isolate at that point.

Meanwhile, we also enforce a CPU time limit of 50ms. In practice, a script that allocates tons of memory tends to run out of CPU time before it can hit the 8x heap limit (especially as the GC slows things down when approaching the limit).

关于c++ - 如何判断 v8 isolate 实例使用了太多内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39626567/

相关文章:

C++ 作用域和 Google V8 脚本上下文

c++ - 在类中包装 V8 时出现段错误?

c++ - 在此示例中在 FP 上使用 == 是否安全

c++ - 将日志宏转换为 Objective-C 字符串

javascript - V8 内部 - 匿名函数的处理

javascript - Google Chrome 61.0.3163.79 中的 Canvas 在 Linux 上太慢

javascript - 如何使用 V8 从 C++ 访问和调用 Javascript 对象属性和方法?

c++ - 如何不使用命令行参数编译 CMakeLists.txt 的部分内容?

c++ - 如何使用 QTimeLine 为两个值设置动画

javascript - V8 实际上在哪里使用原始 javascript 代码?