我正在使用spawn-child npm包来生成一个shell,我运行一个最初构建在C ++上的二进制文件。我为二进制文件提供了Stdin,然后二进制文件将每秒发送一次Stdout。在节点部分,一旦我开始从二进制文件接收Stdout,我就有一个on
监听器,它看起来像stdout.on('data', function (data) {})
,我将这些数据发送到SSE通道。
一切都运行良好,但主要关注的是节点进程的持续内存增长,当我每次用Stdin命中二进制时,我会看到。我已经概述了我的代码看起来如何,是否有一种优雅的方式来控制这种内存增长,如果是这样请分享。
var sseChannel = require('sse-channel'),
spawnCommand = require('spawn-command'),
cmd = 'path to the binary file',
globalArray = [],
uuid = require('uuid');
module.exports = function(app) {
var child = spawnCommand(cmd),
privateChannel = new sseChannel({
historySize: 0,
cors: {
origins: ['*']
},
pingInterval: 15 * 1000,
jsonEncode: false
});
srvc = {
get: function(req, res) {
globalArray[uuid.v4()] = res;
child.stdin.write('a json object in a format that is expected by binary' + '\n'); // req.query.<queryVal>
child.stdout.on('data', function(data) {
privateChannel.send(JSON.stringify(data));
});
},
delete: function(sessionID) {
var response = globalArray[sessionID];
privateChannel.removeClient(response);
response.end();
delete globalArray[sessionID];
}
}
}
此代码只是为了枚举它在应用中的外观。在这种情况下,点击Run代码段不起作用。
我以2个不同的间隔收集了heapdump,这就是统计数据的外观,Typed Array值大幅增加,可以做些什么来维持或抑制Typed Array的增长,
答案 0 :(得分:5)
问题在于,您正在生成一个进程,然后为您的http服务器的每个请求添加一个新的data
事件处理程序,该请求永远不会被删除。所以这就解释了为什么即使在gc之后内存使用也不会下降。
另一个(无关的)问题是,如果您使用单个子进程处理多个传入请求,则可能会遇到混合不同请求的响应的问题(您不能假设一个data
事件将包含仅特定请求的数据)。如果子进程是基于node.js的,您可以使用它设置ipc通道,然后只是来回传递常规JavaScript值,而不是设置stdout
处理/解析。如果子节点不是基于node.js的,或者您想要一个替代(no-ipc)解决方案,则可以设置一个队列,将所有请求推送到该队列,然后使用一个处理队列并按顺序响应每个请求的函数(只有在您确定已收到当前请求的子进程的所有输出后,才会转到下一个请求。)
如果您认为子进程仅用于单个请求,则需要调整代码以针对每个请求生成一次(在spawn()
内移动get()
)。