上传图片时 Nodejs 内存填得太快~10MB
Nodejs memory gets filled too quick when uploading images ~10MB
总结
通过 JIMP 将图像从 Nodejs 后端上传到 AWS S3 会填满内存堆。
工作流程
- 前端(反应)通过表单提交将图像发送到 API
- 服务器解析表单数据
- JIMP 正在旋转图像
- 如果宽度 > 1980 像素,JIMP 正在调整图像大小
- JIMP 创建缓冲区
- 缓冲区正在上传到 S3
- Promise 已解决 -> 图像元数据(URL、存储桶名称、索引等)保存在数据库中 (MongoDB)
背景
服务器托管在 Heroku 上,只有 512MB 内存。上传较小的图像和所有其他请求都工作正常。但是,在只有一个用户在线的情况下,上传大于 ~8MB 的单个图像时,应用程序会崩溃。
目前调查
我已经尝试在我的本地环境中复制它。由于我没有内存限制,应用程序不会崩溃,但上传 10MB 图像时内存使用量约为 870MB。一个 6MB 的图像会占用大约 60MB 的 RAM。我已经更新了所有 npm 包,并尝试禁用对图像的任何处理。
我已尝试查找内存泄漏,如以下屏幕截图所示,但是,按照与上述相同的工作流程处理同一图像 (6MB) 并拍摄 3 个堆快照会占用大约 60MB 的 RAM。
首先,我认为问题是图像处理(调整大小)占用太多内存,但这并不能解释 60MB(对于 6MB 图像)和 800MB(对于 10MB 图像)之间的巨大差距。
然后我认为它与占用大约 30% 内存的项目 "system / JSArrayBufferData"(参见 ref2)有关。然而,这个项目总是在那里,即使我不上传图片。它只是在我停止在 "Chrome dev tools" 下的 "Memory tab" 中录制快照之前出现的。但是,我仍然不能 100% 确定它到底是什么。
现在,我认为这与 "TimeList"(参见 ref3)有关。我认为这是由于等待文件上传到 S3 的超时。但是,在这里,我也完全不确定为什么会这样。
以下是在我看来 Chrome Inspector 运行 在服务器上带有 --inspect 标志的 Chrome Inspector 运行 快照的重要部分的截图。
Ref1: 显示第 3 个快照的完整项目 - 所有 3 个快照都上传了相同的 6MB 图片。垃圾似乎被正确收集,因为内存大小没有增加
Ref2: 显示第三张快照的结尾,就在我停止录制之前。不确定 "system / JSArrayBufferData" 是什么。
Ref3: 显示第 5 个快照的结尾,这是一张 10MB 的图像。那些小的、连续的尖峰是似乎与超时有关的项目 "TimeList"。它们似乎在服务器等待 AWS 响应时出现。这似乎也是填满内存的原因,因为上传小于 10MB 的内容时该项目不存在。
Ref4: 显示第 5 个快照的立即结束,就在停止录制之前。 "system / JSArrayBufferData" 再次出现,但是只出现在最后。
问题
不幸的是,我不确定如何表达我的问题,因为我不知道问题是什么,也不知道我真正需要注意什么。如果有任何提示或经验,我将不胜感激。
高内存消耗是由包 "Jimp" 引起的,该包已用于读取文件、旋转文件、调整文件大小以及创建缓冲区以上传到文件存储系统。
读取文件的部分,即Jimp.read('filename')导致了内存问题。这是一个已知错误,如下所示:https://github.com/oliver-moran/jimp/issues/153
现在,我已经切换到 'sharp' 图片处理包,现在可以轻松上传大于 10MB 的图片和视频了。
我希望它对 运行 的人也有帮助。
干杯
总结
通过 JIMP 将图像从 Nodejs 后端上传到 AWS S3 会填满内存堆。
工作流程
- 前端(反应)通过表单提交将图像发送到 API
- 服务器解析表单数据
- JIMP 正在旋转图像
- 如果宽度 > 1980 像素,JIMP 正在调整图像大小
- JIMP 创建缓冲区
- 缓冲区正在上传到 S3
- Promise 已解决 -> 图像元数据(URL、存储桶名称、索引等)保存在数据库中 (MongoDB)
背景
服务器托管在 Heroku 上,只有 512MB 内存。上传较小的图像和所有其他请求都工作正常。但是,在只有一个用户在线的情况下,上传大于 ~8MB 的单个图像时,应用程序会崩溃。
目前调查
我已经尝试在我的本地环境中复制它。由于我没有内存限制,应用程序不会崩溃,但上传 10MB 图像时内存使用量约为 870MB。一个 6MB 的图像会占用大约 60MB 的 RAM。我已经更新了所有 npm 包,并尝试禁用对图像的任何处理。
我已尝试查找内存泄漏,如以下屏幕截图所示,但是,按照与上述相同的工作流程处理同一图像 (6MB) 并拍摄 3 个堆快照会占用大约 60MB 的 RAM。
首先,我认为问题是图像处理(调整大小)占用太多内存,但这并不能解释 60MB(对于 6MB 图像)和 800MB(对于 10MB 图像)之间的巨大差距。
然后我认为它与占用大约 30% 内存的项目 "system / JSArrayBufferData"(参见 ref2)有关。然而,这个项目总是在那里,即使我不上传图片。它只是在我停止在 "Chrome dev tools" 下的 "Memory tab" 中录制快照之前出现的。但是,我仍然不能 100% 确定它到底是什么。
现在,我认为这与 "TimeList"(参见 ref3)有关。我认为这是由于等待文件上传到 S3 的超时。但是,在这里,我也完全不确定为什么会这样。
以下是在我看来 Chrome Inspector 运行 在服务器上带有 --inspect 标志的 Chrome Inspector 运行 快照的重要部分的截图。
Ref1: 显示第 3 个快照的完整项目 - 所有 3 个快照都上传了相同的 6MB 图片。垃圾似乎被正确收集,因为内存大小没有增加
问题
不幸的是,我不确定如何表达我的问题,因为我不知道问题是什么,也不知道我真正需要注意什么。如果有任何提示或经验,我将不胜感激。
高内存消耗是由包 "Jimp" 引起的,该包已用于读取文件、旋转文件、调整文件大小以及创建缓冲区以上传到文件存储系统。
读取文件的部分,即Jimp.read('filename')导致了内存问题。这是一个已知错误,如下所示:https://github.com/oliver-moran/jimp/issues/153
现在,我已经切换到 'sharp' 图片处理包,现在可以轻松上传大于 10MB 的图片和视频了。
我希望它对 运行 的人也有帮助。
干杯