微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js – 当进程内存不足时如何处理V8引擎崩溃

node控制台和Qt5的基于V8的 QJSEngine都可以通过以下代码崩溃:

a = []; for (;;) { a.push("hello"); }

崩溃前节点的输出

Fatal error: JS Allocation Failed - process out of memory

崩溃前qjsengine输出

#
# Fatal error in JS
# Allocation Failed - process out of memory
#

如果我在调试器下运行我的qjsengine测试应用程序(见下文),它会在V8代码显示v8::internal::OS::DebugBreak调用.如果我将调用qjsengine :: evaluate的代码包装到__try -__(SEH)之外,那么应用程序不会崩溃,但此解决方案是特定于Windows的.

问题:有没有办法在节点和Qt应用程序中以独立于平台的方式处理v8 :: internal :: OS :: DebugBreak?

=== qjsengine测试代码===

开发环境:QtCreator,Qt5和Windows SDK 7.1,在Windows XP SP3上

qjsengineTest.pro:

TEMPLATE = app
QT -= gui
QT += core qml
CONfig -= app_bundle
CONfig += console
SOURCES += main.cpp
TARGET = qjsengineTest

没有SEH的main.cpp(这会崩溃):

#include <QtQml/qjsengine>

int main(int,char**)
{
  try {
    qjsengine engine;
    QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
    qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
  } catch (...) {
    qDebug("Exception");
  }
  return 0;
}

带有SEH的main.cpp(这不会崩溃,输出“致命异常”):

#include <QtQml/qjsengine>
#include <Windows.h>

void runtest()
{
  try {
    qjsengine engine;
    QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
    qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
  } catch (...) {
    qDebug("Exception");
  }
}

int main(int,char**)
{
  __try {
    runtest();
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    qDebug("Fatal exception");
  }
  return 0;
}

解决方法

我不相信有一种跨平台的方法来捕获V8致命错误,但即使有,或者如果有某种方法将它们捕获到你关心的所有平台上,我也不确定那会给你带来什么.

问题是V8使用global flag来记录是否发生了致命错误.一旦设置了该标志,V8将拒绝任何创建新JavaScript上下文的尝试,因此无论如何都没有必要继续.在捕获最初的致命错误后尝试执行一些良性JavaScript代码.如果我是对的,你马上就会得到另一个致命的错误.

在我看来,正确的是Node和Qt将V8配置为不首先引发致命错误.既然V8支持隔离和内存约束,那么杀死致命错误的进程就不再合适了.不幸的是,看起来V8的错误处理代码还没有完全支持这些较新的功能,并且仍然假设内存不足的情况总是无法恢复的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐