Heroku Node.js内存仍然可用的应用程序'allocation failure scavenge might not succeed'



我遇到堆内存错误,导致我的应用程序崩溃。但我的应用程序有可用内存。

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/wwwnode --optimize_for_size bin/www都根据dyno大小将heap_size_limit更改为大致相同的量。所以后来我取了--optimize_for_size

最新更新