2016-03-28 58 views
4

我正在使用spawn-child npm包来产生一个shell,我运行一个最初建立在C++上的二进制文件。我将Stdin提供给二进制文件,然后二进制文件每秒都会发送Stdout。在节点部分,一旦我开始从二进制接收标准输出,我有一个on听众,它看起来像stdout.on('data', function (data) {}),我发送这些数据到SSE频道。Node.js虚拟内存不断增加,同时使用子进程

一切工作正常,但主要关注的是节点进程的不断内存增长,我看到当我每次用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]; 
 
    } 
 
    } 
 
}

这个代码仅仅是列举它是什么样子的应用程序。在这种情况下,运行代码片段不起作用。

我收集堆转储在2周不同的时间间隔,这是如何统计看,有一个巨大的增加类型数组值,什么可以做,以保持或抑制类型数组的增长,

enter image description here

enter image description here

+0

你是否每次请求调用'srvc.get()'? – mscdex

+0

是的,这是正确的。每次发出请求时,都会有一个stdin提供给二进制文件,stdout'on'监听器会记录数据。 – Sai

+0

srvc'的范围是什么?每次模块调用时你是否有意覆盖它?请向我们展示完整的代码。 – Bergi

回答

5

的问题是,你一旦产卵的过程,然后添加一个新的data事件处理程序的每个请求HTTP服务器是永远不会被删除。所以这可以解释为什么即使在gc之后内存使用也不会下降。

另一个(无关)的问题是,如果你使用的是单一的子进程来处理多个传入的请求,你可以运行到混合反应的不同要求(的问题,你不能假设一个data事件将包含特定请求的数据)。如果子进程是基于node.js的,则可以使用它设置一个ipc通道,然后只传递常规JavaScript值而不是设置处理/解析。如果孩子不是基于node.js的,或者你想要一个替代方案(no-ipc)解决方案,你可以设置一个队列,所有的请求都被推送到队列中,然后有一个处理队列并响应每个请求的函数(只有当你以某种方式确定你已经接收到当前请求的子进程的所有输出时才移动到下一个请求)。

如果您的子进程仅用于单个请求,您需要调整代码以便每次请求产生一次(代码spawn(),内部为get())。

+0

我试图您正在提议的精确解决方案,但它的一面是,如果我产卵的处理为每一个请求,那么我将在具有在该特定的二进制文件(C++程序),用于每一个请求运行时,最终我会处理100个请求,以便产生许多进程会非常昂贵的情况。 – Sai

+1

这就是为什么我给出了第二个问题的多种解决方案(包括:使用ipc和/或队列)。 – mscdex

+0

在这种使用情况下我处理事件流中,当一个请求,即制成如果一个标准输入被发送到子过程,则该过程将发射数据(stdouts)连续,这意味着我想我不能有一个队列的逻辑来使后续请求一旦当前请求时..我的意思是我提出请求,这将是积极的,然后应用程序应该允许活动的任何请求#.. – Sai

相关问题