- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 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/
我有一个 k*n矩阵 X 和 k*k矩阵A。对于X的每一列,我想计算标量 X[:, i].T.dot(A).dot(X[:, i]) (或者,数学上, Xi' * A * Xi )。 目前,我有一个
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我是 VueJS 的新手。我已经使用 vuetify/webpack-ssr 模板创建了一个项目,现在我想创建一个登录页面,但是没有显示表单,控制台给了我以下信息: [Vue warn]: Unkno
我尝试将 value 插入到 C++ vector v 之前的第 i 元素(或元素 (i-1) 之后) )。代码很简单 v.insert(v.begin() + i, value); 我确信当 i 介
我需要显示使用合并排序算法排序的 vector 。然而,当我使用 v.begin() 时,我的 friend 使用 v.data() 来传递 vector 。他的代码运行良好,而我的却不行。请解释。
这是我的命令(url1、url2、url3、url4 是占位符): ffmpeg -i url1 -i url2 -i url3 -i url4 -filter_complex “[1:v:0] [1
我以前用过Vue,我知道怎么用v-for渲染元素序列,v-if或v-show有条件地显示元素,并且 v-model例如,控制段落的内容。 但现在我需要对 DOM 进行更精细的控制: 我有一个range
我正在学习所有权和借用。 borrow1 和borrow2 的区别在于在borrow2 打印时使用了&: fn borrow1(v: &Vec) { println!("{}", &v[10]
我找不到一种方法来选择不同的选项来渲染 v-for 中的文本。是否有可能或者我是否需要以不同的方式构建逻辑来执行类似于下面的代码的操作? // i
Iterable 的三个直接子类型是 Map , Seq , 和 Set .除了性能问题之外,似乎还有一个 Seq是从整数到值的映射,以及 Set是从值到 bool 值的映射(如果值在集合中,则为 t
我想应用一个计算方法,如果键存在则增加值,否则将 1。有 Map map = new HashMap<>(); 我不明白为什么 for (int i = 0; i v != null ? v++ :
标准(IEEE 754/C)是否保证以下代码断言永远不会失败? int main() { for ( /* all possible float / double values */ )
代码由Vue语言编写,使用Element-ui框架, 如果一个对象包含某些内容,则会显示该内容,如果不包含则禁用菜单按钮。 输出应该是这样的: a、b(禁用)、c、d、e 但我的是这样的: a、a(禁
如果我这样做: {{ morevalue }} {{ value }} v-else 中的跨度也会在第二个 V-FOR 上循环,即使它上面没有任何 v-for,为什么? 这是
如果我这样做: {{ morevalue }} {{ value }} v-else 中的跨度也会在第二个 V-FOR 上循环,即使它上面没有任何 v-for,为什么? 这是
我将 Vue.js 与 Vuetify 一起使用,我正在尝试使用 v-data-table 从后端加载菜单列表并使用 对其设置一些权限v-switches 但我在尝试 v-model 数组时遇到问题:
我在 Java 的流式操作中努力维护我想要的数据结构,这很可能是由于缺乏正确的理解和实践。 public class Main { public static void main(String
我正在尝试为匹配中的每个匹配呈现一些 HTML,但是,我不太确定 实际上是正确的。 更具体地说,我不确定我是否可以使用 v-bind:match='match'在与循环相同的元素上 v-for='ma
所以我想知道为什么这个 v-if 和 v-else 语句不起作用,为什么我要以不同的方式解决它。 代码如下 Required: Select a Workflow {{ isChain ?
我有一个 VueJS 组件 ,我在同一个模板中使用了两次来显示两组不同的数据。每个都显示在自己的 使用 v-if 切换的容器在导航选项卡上。 似乎这些组件被实例化为同一个实例。我调用 console
我是一名优秀的程序员,十分优秀!