Heroku Node.js 应用程序“分配失败清除可能不会成功”,内存仍然可用

Das*_*uss 5 javascript heap-memory heroku node.js dyno

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

\n
 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 \n
Run Code Online (Sandbox Code Playgroud)\n
app/web.1 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory \n
Run Code Online (Sandbox Code Playgroud)\n

错误发生在 512mb 左右。我的标准 2X 测功机有 1GB。

\n

节点版本是16.17.0。据我了解,超过 12 的节点版本的堆限制基于可用内存。

\n
\n

>= 12 的 Node 版本可能不需要使用 --optimize_for_size 和 --max_old_space_size 标志,因为 JavaScript 堆限制将基于可用内存。\n src

\n
\n

我考虑了 512mb 测功机上的一名工人。但是worker dyno会导致整个应用程序崩溃吗?如果是这样的话,错误不会来自app/worker.1app/web.1日志中显示的情况吗?

\n

更新

\n

我想出了如何重新创建堆限制分配错误。这让我得到了更多的线索。

\n

我在512mb hobby dyno上得到大约256mb的错误。

\n

我在1024mb(1gb) 标准 2X上得到大约512mb的错误。

\n

所以它总是可用内存的一半。我不确定这是否是 heroku 上的某种设置。

\n

更新2

\n

使用 v8 节点模块(包含在节点中)我可以获得更多数据:

\n
 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 \n
Run Code Online (Sandbox Code Playgroud)\n
app/web.1 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory \n
Run Code Online (Sandbox Code Playgroud)\n

我可以看到heap_size_limit业余测功机上的值为 259,2X 标准测功机上的值为 515。

\n
   \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n   \xe2\x94\x82           (index)           \xe2\x94\x82   Values    \xe2\x94\x82\n   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n   \xe2\x94\x82       total_heap_size       \xe2\x94\x82 \'268.08 MB\' \xe2\x94\x82\n   \xe2\x94\x82 total_heap_size_executable  \xe2\x94\x82  \'2.25 MB\'  \xe2\x94\x82\n   \xe2\x94\x82     total_physical_size     \xe2\x94\x82 \'266.73 MB\' \xe2\x94\x82\n   \xe2\x94\x82    total_available_size     \xe2\x94\x82  \'3.31 MB\'  \xe2\x94\x82\n   \xe2\x94\x82       used_heap_size        \xe2\x94\x82 \'263.69 MB\' \xe2\x94\x82\n   \xe2\x94\x82       heap_size_limit       \xe2\x94\x82 \'259.00 MB\' \xe2\x94\x82\n   \xe2\x94\x82       malloced_memory       \xe2\x94\x82  \'1.01 MB\'  \xe2\x94\x82\n   \xe2\x94\x82    peak_malloced_memory     \xe2\x94\x82  \'3.03 MB\'  \xe2\x94\x82\n   \xe2\x94\x82      does_zap_garbage       \xe2\x94\x82  \'0.00 MB\'  \xe2\x94\x82\n   \xe2\x94\x82  number_of_native_contexts  \xe2\x94\x82  \'0.00 MB\'  \xe2\x94\x82\n   \xe2\x94\x82 number_of_detached_contexts \xe2\x94\x82  \'0.00 MB\'  \xe2\x94\x82\n   \xe2\x94\x82  total_global_handles_size  \xe2\x94\x82  \'0.16 MB\'  \xe2\x94\x82\n   \xe2\x94\x82  used_global_handles_size   \xe2\x94\x82  \'0.16 MB\'  \xe2\x94\x82\n   \xe2\x94\x82       external_memory       \xe2\x94\x82 \'18.53 MB\'  \xe2\x94\x82\n   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

Das*_*uss 7

总而言之:

--max-old-space-size=1024进入 procfile。

web: node --max-old-space-size=1024 bin/www

Run Code Online (Sandbox Code Playgroud)

或者

添加环境变量键:NODE_OPTIONS值为--max_old_space_size=1024

细节

最初我的Procfile是

web: node --optimize_for_size  bin/www

Run Code Online (Sandbox Code Playgroud)

我有一个环境变量 key 的--max-old-space-sizevalue 1024

这不是列出环境变量的正确方法。它应该是关键:NODE_OPTIONS值为--max_old_space_size=1024。我自己还没有尝试过这个。

相反,我将 procfile 更改为:

web: node --optimize_for_size --max-old-space-size=1024 bin/www

Run Code Online (Sandbox Code Playgroud)

这也有效。

我不确定--optimize_for_size会做什么,因为node bin/wwwvsnode --optimize_for_size bin/wwwheap_size_limit根据测功机大小将其更改为大约相同的数量。所以后来我就拿--optimize_for_size出来了。