2016-03-28 120 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

相關問題