NodeJS和Lambda中的ENOMEM

yi0zb3m4  于 2023-01-25  发布在  Node.js
关注(0)|答案(1)|浏览(146)

我正在运行一个图像处理服务,使用节点画布,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等)。

cu6pst1q

cu6pst1q1#

溶液

在重新阅读了我自己的帖子并做了一些额外的研究后,我突然意识到节点画布没有被正确清理。我不知道我是如何忽视这一点的,因为报告的pango/cairo内存泄漏比我在我的应用程序中看到的要慢得多。
调用execspawn时抛出ENOMEM的事实只是这个问题的一个症状。根本问题是NodeCanvas的重复使用占用了内存。一旦进程内存命中率〉50%,spawn调用将由于我上面强调的NodeJS bug而失败。
最终帮助我解决这个问题的帖子是this。我还使用了fabricjs,这可能也是部分原因。

canvas.clear()
canvas.dispose()
canvas.interactive && canvas.removeListeners()

在实现这个之后,内存增长慢了很多,以至于在内存增长成为问题之前就删除了Lambda容器。

相关问题