NodeJS Stream Drain内存不足问题

我有一个问题,试图从elasticsearch检索数据(操作系统Ubuntu,节点v4.2.6,res对象来自明确作为一个可写的stream)。

我没有故意使用elasticsearch.js驱动程序。 如果我使用ES驱动程序,结果保持不变。

这是我的代码:

function getNextChunk() { console.log(process.memoryUsage()); console.log("Getting chunks..."); var options = { method : 'POST', url : myHost + '/_search/scroll', json : true, body : { scroll: '60s', scroll_id: globalScope.scrollId }}; request.post(options, function (err, resp, data) { if (err) return console.log(err); if (!data.hits.hits.length) { console.log("Done!"); return res.end(); } if (!res.write(JSON.stringify(data.hits.hits))) res.once('drain', function() { console.log("Draining..."); process.nextTick(getNextChunk); }) else process.nextTick(getNextChunk); }); } 

这里是输出:

 { rss: 165621760, heapTotal: 140918368, heapUsed: 116827240 } Getting chunks... Draining... { rss: 178941952, heapTotal: 153020000, heapUsed: 122942472 } Getting chunks... Draining... { rss: 191905792, heapTotal: 164065120, heapUsed: 140290016 } Getting chunks... 

(……)

 Draining... { rss: 402944000, heapTotal: 358359648, heapUsed: 328087560 } Getting chunks... Draining... { rss: 414441472, heapTotal: 369453920, heapUsed: 345375496 } Getting chunks... Killed 

正如你所看到的,heapUsed正在增加,直到进程被操作系统杀死。 我想我在某个地方失去了一些东西,但我无法弄清楚。

顺便说一下,我试着用排水事件一一写下每一个命中,但仍然是一样的…

从这里编辑

我用这个代码做了一个新的testing:

 var data = {}; function safeWrite(err, resp, newData) { if (newData) data = newData; if (err) return console.log('Error !'); if (!data.hits.hits.length) return console.log('Done !'); while (data.hits.hits.length) { if (!res.write(JSON.stringify(data.hits.hits.pop()))) { res.once('drain', safeWrite); break; } } if (!data.hits.hits.length) process.nextTick(getNextChunk); } function getNextChunk() { console.log(process.memoryUsage()); console.log("Getting chunks..."); var options = { method : 'POST', url : myHost + '/_search/scroll', json : true, body : { scroll: '1m', scroll_id: state.scrollId }}; request.post(options, safeWrite); } getNextChunk(); 

有趣的是,如果我从另一个AWS服务器调用express,它会得到相同的结果。 内存在增加,并且崩溃节点。 如果我从一个缓慢的连接调用,垃圾收集器把内存回到它的起始水平。 垃圾收集器可能没有时间去完成它的工作吗? 我不这么认为,但是…

感谢您的帮助!