node.js - 上传图片时,Nodejs 内存填得太快了 ~10MB
问题描述
概括
通过 JIMP 从 Nodejs 后端将图像上传到 AWS S3 会占用大量内存。
工作流程
- 前端(react)通过表单提交将图像发送到 API
- 服务器解析表单数据
- JIMP 正在旋转图像
- 如果 > 1980px 宽,JIMP 正在调整图像大小
- JIMP 创建缓冲区
- 缓冲区正在上传到 S3
- 已解决的承诺 -> 保存在数据库 (MongoDB) 中的图像元数据(URL、存储桶名称、索引等)
背景
服务器托管在 Heroku 上,只有 512MB RAM。上传较小的图像和所有其他请求都可以正常工作。但是,当上传大于约 8MB 的单个图像时,应用程序会崩溃,并且只有一个用户在线。
调查至今
我试图在我的本地环境中复制它。由于我没有内存限制,因此应用程序不会崩溃,但上传 10MB 图像时内存使用量约为 870MB。一个 6MB 的图像保持在 60MB 左右的 RAM 使用量。我已经更新了所有的 npm 包,并试图禁用任何图像处理。
我尝试查找以下屏幕截图中的内存泄漏,但是,对于同一个图像 (6MB) 遵循与上述相同的工作流程并拍摄 3 个堆快照会产生大约 60MB 的 RAM 使用量。
首先,我认为问题在于图像处理(调整大小)占用了太多内存,但这并不能解释 60MB(6MB 图像)和 10MB 图像大约 800MB 之间的巨大差距。
然后我认为它与占用大约 30% 内存的项目“system / JSArrayBufferData”(见 ref2)有关。但是,这个项目总是在那里,即使我不上传图片。它仅在我在“Chrome 开发工具”下的“内存选项卡”中停止录制快照之前出现。但是,我仍然不能 100% 确定它到底是什么。
现在,我相信这与“TimeList”有关(见 ref3)。我认为它来自等待文件上传到 S3 的超时。但是,在这里,我也完全不确定为什么会发生这种情况。
以下是我认为在 nodejs 上运行在带有 --inspect 标志的服务器上的 Chrome Inspector 快照的重要部分的屏幕截图。
Ref1:显示第 3 个快照的全部项目 - 所有 3 个快照都上传了相同的 6MB 图像。垃圾似乎已正确收集,因为内存大小没有增加 Ref2: Shows end 3rd Snapshot,就在我停止录制之前。不确定“系统/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 的图像和视频。
我希望它也对遇到这种情况的人有所帮助。
干杯
推荐阅读
- android - scanForPeripherals 报告几十个随机外围设备(一个物理设备)
- python - 将嵌套值添加到由值列表组成的当前字典
- python - 打开 CV RTSP 相机缓冲滞后
- python - Vaex 日期时间比较
- python - 扫雷:Python 错误。AttributeError:类型对象没有属性
- java - 三星设备上 performLaunchActivity 期间的 Android RuntimeException
- c# - 如何编组包含从 C 到 C# 的联合的结构
- datatable - p:datatable 过滤器在更新 7.0 到 8.0 后不再正常工作
- javascript - 如何在angularjs中使用_.map使用三元运算符
- html - Bootstrap pre element with overflow-x: auto 具有窗口的宽度而不是父级