C++ 如何判断v8孤立实例使用了太多内存?

C++ 如何判断v8孤立实例使用了太多内存?,c++,v8,embedded-v8,C++,V8,Embedded V8,我正在使用Google的v8引擎在我的应用程序中嵌入javascript。在某些时候,我将调用用户提供的代码,我希望确保它不会因为分配太多内存而表现不好。当前,当javascript试图使数组过大或调整其大小时,例如,我收到一条不客气的消息: # # Fatal error in CALL_AND_RETRY_LAST # Allocation failed - process out of memory # 然后整个过程就崩溃了。显然,这是不可接受的。我需要能够运行用户提供的代码,但是。。。

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

#
# Fatal error in CALL_AND_RETRY_LAST
# Allocation failed - process out of memory
#
然后整个过程就崩溃了。显然,这是不可接受的。我需要能够运行用户提供的代码,但是。。。在引擎执行之前手动检查所有代码是不可行的

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

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

创建隔离时设置自定义数组_缓冲区分配器,该分配器跟踪正在使用的内存量,并在内存使用率过高时终止隔离>我的分配器的分配函数从未被调用

使用跟踪内存使用情况的函数调用AddMemoryLocationCallback,并在分配超过一定数量时尝试通过TerminateExecution()终止隔离。该函数确实会被调用,但在该函数只报告使用了几兆字节后,我出现了内存不足错误,而我知道,行为不好的v8函数创建的数据远远大于此值

通过SetFatalErrorHandler设置致命错误处理程序并尝试在那里调用TerminateExecution。虽然会调用此函数,但它不能防止进程崩溃


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

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

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

(也许吧。在2013-2014年的时间框架内,似乎有很多关于这一点的事情在发生。谷歌的人说,正确的做法是让v8扼杀这一过程——很多人认为这是愚蠢的。我看不到任何解决方案)

编辑:邮件列表的响应是您不能这样做。如果补丁对性能没有影响,他们会接受它

编辑:这只是另一个帖子,有人发布了一个在非恶意情况下避免OOM的非常好的方法:

我将堆限制设置为实际需要限制的8倍。然后,每次之后 调用隔离,我检查内存使用是否超过 预期限制。如果是这样,我调用垃圾收集。如果它还是 超过限制之后,我在那个点终止隔离

同时,我们还强制执行50毫秒的CPU时间限制。在实践中 分配大量内存的脚本往往会耗尽CPU时间 在它达到8倍堆限制之前(特别是当GC减慢速度时) 接近极限时下降)


谢谢,虽然我刚刚尝试了这个建议,但不幸的是,它没有起作用。我已经用我目前为止尝试过的东西更新了上面的描述。Chrome是多进程的,所以他们不必担心javascript会破坏进程。。因为这只是一个标签,无论如何都是无效的。嗯。。。那有点像b!tch。。。这意味着v8可能不是js引擎的最佳选择。如果你不知道,我可以。我读到的内容说,很难(大量的工作,不一定技术上困难)检测是否存在“真实”的内存不足情况或“人为”(意思是超出某些用户定义的范围)内存不足情况,并且在这两种情况下表现不同。它是为支持chrome而构建的。它适用于铬合金。