简体   繁体   English

Node.js虚拟内存在使用子进程时不断增加

[英]Node.js virtual memory increases constantly while using child process

I'm using spawn-child npm package to spawn a shell where i run a binary file which was originally built on C++. 我正在使用spawn-child npm包来生成一个shell,我运行的二进制文件最初是在C ++上构建的。 I provide Stdin's to the binary and then the binary would be sending out the Stdout's constantly for every second. 我为二进制文件提供了Stdin,然后二进制文件将每秒发送一次Stdout。 On the node part once i start receiving the Stdout's from binary i have an on listener which would look something like stdout.on('data', function (data) {}) where i send these data's to the SSE channel. 在节点部分,一旦我开始从二进制文件接收Stdout,我就有一个on listener,看起来像stdout.on('data', function (data) {}) ,我将这些数据发送到SSE通道。

Everything is working fine but the major concern is the constant memory growth of node process that i see when i hit the binary everytime with an Stdin. 一切都运行良好,但主要关注的是节点进程的持续内存增长,我看到每当我用Stdin命中二进制时。 I have outlined how my code looks, is there an elegant way to control this memory growth, if so please share. 我已经概述了我的代码看起来如何,是否有一种优雅的方式来控制这种内存增长,如果是这样请分享。

 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]; } } } 

This code is just to enumerate how it would look in the app. 这段代码只是为了枚举它在应用程序中的外观。 Hitting the Run code snippet would not work in this case. 在这种情况下,点击运行代码段不起作用。

I collected heapdump at 2 different intervals and this is how the statistics looks, there is a tremendous increase in the Typed Array value, what could be done to maintain or suppress the growth of Typed Array, 我以2个不同的间隔收集了heapdump,这就是统计数据的外观,Typed Array值有了很大的增长,可以做些什么来维持或抑制Typed Array的增长,

在此输入图像描述

在此输入图像描述

The problem is that you're spawning a process once and then adding a new data event handler for every request to your http server that never gets removed. 问题是你产生一个进程一次,然后为你的http服务器的每个请求添加一个新的data事件处理程序,永远不会被删除。 So this would explain why the memory usage never drops even after gc. 所以这可以解释为什么即使在gc之后内存使用量也不会下降。

Another (unrelated) problem is that if you are using your single child process to process multiple incoming requests, you can run into the problem of mixing responses for different requests (you cannot assume that one data event will contain only the data for a particular request). 另一个(无关的)问题是,如果您使用单个子进程处理多个传入请求,则可能会遇到混合不同请求的响应的问题(您不能假设一个data事件包含特定请求的数据) )。 If the child process is node.js-based, you could set up an ipc channel with it and then just pass regular JavaScript values back and forth instead of setting up stdout handling/parsing. 如果子进程是基于node.js的,您可以使用它设置ipc通道,然后只是来回传递常规JavaScript值,而不是设置stdout处理/解析。 If the child isn't node.js-based or you want an alternative (no-ipc) solution, you could set up a queue that all requests get pushed onto and then have a function that processes the queue and responds to each request serially (only moving onto the next request once you have somehow determined you have received all output from the child process for the current request). 如果子节点不是基于node.js的,或者您想要一个替代(no-ipc)解决方案,则可以设置一个队列,将所有请求推送到该队列,然后使用一个处理队列并按顺序响应每个请求的函数(只有在您确定已收到子进程的当前请求的所有输出后,才会转到下一个请求)。

If you instead meant for the child process to only be used for a single request, you will need to tweak your code to spawn once per request instead (moving spawn() inside get() ). 如果您的子进程仅用于单个请求,则需要调整代码以针对每个请求生成一次spawn()get()移动spawn() get() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM