我遇到堆内存错误,导致我的应用程序崩溃。但我的应用程序有可用内存。
app/web.1 [4:0x4ea2840] 27490 ms: Mark-sweep 505.7 (522.4) -> 502.2 (523.1) MB, 440.3 / 0.0 ms (average mu = 0.280, current mu = 0.148) allocation failure scavenge might not succeed
app/web.1 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
错误发生在512mb左右。我的标准2X dyno有1gb。
节点版本为16.17.0。据我所知,超过12的节点版本的堆限制是基于可用内存的。
>=的节点版本12可能不需要使用--optimize_for_size和--max_old_space_size标志,因为JavaScript堆限制将基于可用内存。src
我认为是512mb dyno上的一个工人。但是工作人员dyno会导致整个应用程序崩溃吗?如果是这样的话,错误不是来自app/worker.1
而不是像日志中显示的那样来自app/web.1
吗?
更新
我发现了如何重新创建堆限制分配错误。这让我得到了更多的线索。
我在512mb业余dyno上得到了大约256mb的错误。
在1024mb(1gb(标准2X上,我得到的错误大约为512mb。
所以它总是可用内存的一半。我不确定这是否是heroku的某种设置。
更新2
使用v8节点模块(包含在节点中(,我可以获得更多数据:
const v8 = require('v8');
// added the code below to a route that caused a memory leak
const heapStats = v8.getHeapStatistics();
const heapStatsMB = heapStats;
for (const key in heapStatsMB) {
heapStatsMB[key] = `${(((heapStatsMB[key] / 1024 / 1024) * 100) / 100).toFixed(2)} MB`;
}
console.table(heapStatsMB);
我可以看到heap_size_limit
在业余测功机上是259,在2X标准测功机中是515。
┌─────────────────────────────┬─────────────┐
│ (index) │ Values │
├─────────────────────────────┼─────────────┤
│ total_heap_size │ '268.08 MB' │
│ total_heap_size_executable │ '2.25 MB' │
│ total_physical_size │ '266.73 MB' │
│ total_available_size │ '3.31 MB' │
│ used_heap_size │ '263.69 MB' │
│ heap_size_limit │ '259.00 MB' │
│ malloced_memory │ '1.01 MB' │
│ peak_malloced_memory │ '3.03 MB' │
│ does_zap_garbage │ '0.00 MB' │
│ number_of_native_contexts │ '0.00 MB' │
│ number_of_detached_contexts │ '0.00 MB' │
│ total_global_handles_size │ '0.16 MB' │
│ used_global_handles_size │ '0.16 MB' │
│ external_memory │ '18.53 MB' │
└─────────────────────────────┴─────────────┘
TLDR:
--max-old-space-size=1024
进入procfile。
web: node --max-old-space-size=1024 bin/www
或
添加一个环境变量密钥:NODE_OPTIONS
,值为--max_old_space_size=1024
详细信息
最初我的Procfile是
web: node --optimize_for_size bin/www
我有一个--max-old-space-size
的环境变量键,值为1024
。
这不是列出环境变量的正确方式。它应该是关键字:NODE_OPTIONS
,值为--max_old_space_size=1024
。我自己还没试过。
相反,我将我的procfile更改为:
web: node --optimize_for_size --max-old-space-size=1024 bin/www
这也是有效的。
我不确定--optimize_for_size
有什么作用,因为node bin/www
和node --optimize_for_size bin/www
都根据dyno大小将heap_size_limit
更改为大致相同的量。所以后来我取了--optimize_for_size
。