我正在运行一个图像处理服务,使用节点画布,rsvg和libvips来渲染和转换图像。目前,系统运行良好,但在扩展使用后,我开始看到抛出ENOMEM错误。
- 背景**
系统设置注意事项:
- 节点版本为12
- Lambda具有4096MB内存
- Lambda正在传递
--max-old-space-size=3687
和--max-semi-space-size=204
(我似乎无法配置这一点)
根据this问题,spawn和exec处理内存的方式存在问题。据我所知,一旦超过50%的节点内存在使用中,调用exec或spawn将失败,因为它们试图分配超过100%的剩余内存。
从运行的Lambda记录一些数据,我可以看到系统具有以下内容:
os.totalmem() // 5789110272
os.freemem() // 3055075328
process.memoryUsage()
/*
{
"rss": 2521698304,
"heapTotal": 62386176,
"heapUsed": 58013056,
"external": 38297409,
"arrayBuffers": 36799944
}
*/
Lambda的最终日志:
Duration: 109.00 ms Billed Duration: 110 ms Memory Size: 4096 MB Max Memory Used: 2458 MB
在此特定示例中,尝试spawn
并运行fc-cache
命令时引发ENOMEM
。此执行上下文将被重用,因为此调用是在任何主要处理发生之前进行的第一个调用。
- 问题**
我如何调试和解决这个问题?我不确定我应该使用哪种工具,因为这也是在Lambda上。
我知道有一个内存泄漏,但我不确定是我的代码导致的还是类似this的问题。我的代码非常简单,但我使用了几个依赖项,我还没有检查过(Sentry,axios,nodecanvas等)。
1条答案
按热度按时间cu6pst1q1#
溶液
在重新阅读了我自己的帖子并做了一些额外的研究后,我突然意识到节点画布没有被正确清理。我不知道我是如何忽视这一点的,因为报告的pango/cairo内存泄漏比我在我的应用程序中看到的要慢得多。
调用
exec
和spawn
时抛出ENOMEM的事实只是这个问题的一个症状。根本问题是NodeCanvas的重复使用占用了内存。一旦进程内存命中率〉50%,spawn调用将由于我上面强调的NodeJS bug而失败。最终帮助我解决这个问题的帖子是this。我还使用了
fabricjs
,这可能也是部分原因。在实现这个之后,内存增长慢了很多,以至于在内存增长成为问题之前就删除了Lambda容器。