我正在研究一种能够读取大量图像并对这些图像进行处理的软件,例如读取它们的高度,宽度等。 我开始看到一个非常困难的情况,即在将图像URL转换为数据URI时使用的内存。
request.get(imageUrl, function (error, my_data, body) {
var imageBase64Data = new Buffer(body).toString('base64');
var imageData = "data:" + my_data.headers["content-type"] + ";base64," + imageBase64Data;
// using the imageData in image processing using GraphicsMagick module
});
现在我面临的问题是当我的节点进程开始运行并处理这些图像时,它会迅速获得高达1.7GB的内存。 系统开始给出内存错误。
我检查并了解到,用于将图片网址转换为数据URI的缓冲区一旦超出范围就不会删除内存。
请建议或帮助我如何进一步解决此问题。
答案 0 :(得分:0)
不确定这是如何转换为使用带有base64编码的缓冲区的内容。但这就是我翻译缓冲区的方式。 创建新缓冲区时,它会增加heapTotal和heapUsed。虽然这不会转化为使用的块数。删除缓冲区确实会减小堆的大小,但不会与缓冲区中使用的块数成比例。我建议你在消费它之后,尝试设置imageBase64Data = null。节点的内部GC将在下一次扫描中释放这些块。
此外,由于变量是在请求回调处理程序匿名函数内声明的,因此每次发出请求时,它都会在内存中创建一个新的imageBase64Data,imageData。如果您在请求之外声明它并在新数据中引用它可能会覆盖该值。但是你也需要小心,因为你将改变函数内部的值。如果您希望保留对已处理网址的引用,那么我建议您调查memonizing或缓存,这样您就不会反复处理相同的网址。
这是一个简单的测试,它向您展示了将缓冲区设置为null时GC的工作原理。
→ node
> process.memoryUsage()
{ rss: 21639168, heapTotal: 10522624, heapUsed: 5058760 }
> mybuf = require('buffer').Buffer
{ [Function: Buffer]
poolSize: 8192,
from: [Function],
alloc: [Function],
allocUnsafe: [Function],
allocUnsafeSlow: [Function],
isBuffer: [Function: isBuffer],
compare: [Function: compare],
isEncoding: [Function],
concat: [Function],
byteLength: [Function: byteLength] }
> var buf = new mybuf(56789)
undefined
> process.memoryUsage()
{ rss: 24563712, heapTotal: 11571200, heapUsed: 6459632 }
> buf = null
null
> process.memoryUsage()
{ rss: 24756224, heapTotal: 11571200, heapUsed: 6591688 }
> process.memoryUsage()
{ rss: 24805376, heapTotal: 11571200, heapUsed: 6637832 }
> process.memoryUsage()
{ rss: 23359488, heapTotal: 8425472, heapUsed: 5567208 }
>
注意:Nodejs 6.10.2表示使用
创建缓冲区 new Buffer(body)
已被弃用。