javascript - Node.js 中的 ENOMEM 由高虚拟内存使用引起
问题描述
几个月来,我的生产 Node.js (v12) 应用程序中出现 ENOMEM 错误。
这个问题特别难以诊断,因为我的堆总是在 100MB 范围内,并且不会随着时间的推移而增加。因此,不太可能发生节点内存泄漏。
但是,有时 VIRT 内存使用量(由 top cmd 报告)高达 15-20GB,这时节点开始抛出一些“spawn: enomem”错误。
据我所知,即使堆稳定在 100MB,节点也会保留大量虚拟内存。而且我无法诊断它是什么,因为节点首次亮相工具只允许我检查堆。
我在这个问题上花了将近 100 小时,所以任何见解/帮助将不胜感激!
我试过了:
- 手动设置 --max-old-space-size
- 增加服务器上的 RAM
- 将 SWAP 添加到我的服务器并允许 docker 使用该 SWAP
- 使用 chrome 开发工具检查节点堆
- 为我的 docker 容器设置内存限制
- 移动到不同的进程管理器(pm2 而不是 supervisord)
- 升级我所有的包并使用最新的 LTS 版本的节点
- 阅读和理解节点 ENOMEM 的所有谷歌搜索结果
- 了解 Node 如何管理其内存池,尤其是关于堆和 GC。
- 深入了解虚拟、保留、交换和共享内存的 linux 内核概念。
谢谢你的帮助 !
解决方案
我们设法解决了这个问题。请记住,解决方案可能特定于我们自己的项目。
当在大型文件数组(20k+)上使用包“imagemin”和“imagemin-jpegtran”和“imagemin-pngquant”时,我们设法一致地重现错误,并等待所有承诺以 promise.all() 结束. VIRT 内存使用量飙升至 20GB+,执行后从未释放。
我们的解决方案是使用plimit将并发承诺的数量限制为 5 或 10。在相同数量的图像(20k+)上,VIRT 内存使用量从未上升,RES 也没有上升,并且我们停止收到 ENOMEM 错误。
希望这可以帮助那里的人
推荐阅读
- javascript - Javascript 将 JSON 数据解析为多个变量,在内存中存储单独的记录
- python - 卷曲请求在终端中工作正常,但在转换后无法在 python 中工作
- python - 输入函数中的 TensorFlow 数据集方法调用序列
- c# - LinkButton 需要像进度条的 Button 一样工作
- amazon-web-services - AWS AppSync 是否适用于 Xamarin?
- kubernetes - 如何使用 helm 模板创建 toml 数组?
- time-complexity - 这个函数的时间复杂度是 O(n * (n * log n² ))
- ios - 如何使用 Swift 包管理器添加依赖项
- java - 删除添加的按钮 Vaadin
- powershell - PowerShell 检查丢失的 ShadowCopies