Linux因内存不足而终止我的进程,如何查看我使用了多少?

时间:2013-09-03 14:11:38

标签: javascript linux node.js raspberry-pi raspbian

按照上一个问题(Prevent my node.js app to be killed by the OS),我重新制作了下载文件的方法。

为了简短起见,我需要下载一些视频文件(测试文件是3个视频,mp4,~3分钟),我一下子全部下载,这个过程被杀死了,dmesg说了(2个下载完成后) ):

Out of memory: kill process (node) score 824 or sacrifice child
Killed process (node)...

所以我通过一个接一个地下载视频重试,但是在第二次下载时,我得到了完全相同的消息,我的程序被杀了。

有没有办法看到我的代码的哪一部分出错,或者阻止linux杀死我的进程?

BTW,不是三个同时下载吃掉比一个更多的内存?那么为什么我要一个接一个地杀得更快呢?

该应用程序运行在覆盆子pi上,没有GUI,raspbian,我相信它是唯一运行的应用程序(系统进程除外)

编辑: 关于功能的一些细节以及我认为它现在如何工作: 应用程序在节点中启动,而不是在任何浏览器中启动。 由于它一个接一个地下载视频,我认为它会占用更少的内存,但似乎是错误的,因为我在一次性解雇时下载了更多的数据,原因是停止似乎是相同的。

这里是下载功能,以防它可以提供帮助:

file_url的类型为http://adress.com/rpi/test.mp4

function download (file_url, callback){
    var option={host:url.parse(file_url).host, port:80, path:url.parse(file_url).pathname};
    var file_name=url.parse(file_url).pathname.split('/').pop();
    var file=fs.createWriteStream(DOWNLOAD_DIR+file_name);
    //Seems to crash while here:
    http.get(options, function(res){
        res.on('data', function(data){
            file.write(data);
        }).on('end'), function(){
            file.end();
            callback(DOWNLOAD_DIR+file_name);
        });
    });
};

我确信这个功能确实有效,因为我成功地下载了一些文件。

这是我如何进行下载的: ( 这个函数可能无法正常工作,我不要求调试,我永远不会结束它。)

function download_all (list, callback){
    var i=0;
    function follow(){
        i=i+1;
        if (i<list.length){
            download(DOWNLOAD_ADD+list[i], follow);
        }
    }
    download(DOWNLOAD_ADD+list[0], follow);
}

EDIT2:

由于我还没有找到核心转储的方法或者Roman提出的其他解决方案,我在下载时使用了process.memoryUsage来打印它。

heapTotal在整个过程中逐渐增加,在20000万到2500万之间,有些下降。 heapUsed正在迅速增加,并且当高于600万时,常规下降到~2 000 000,其中一些峰值大约为12 000 000。

当这个过程被杀死时,最后一个印刷品是: rss:428 707 840,heapTotal:23 842 176,heapUsed:5 854 164

我注意到如何阅读它,但在我看来,这个过程远远没有吃掉所有的记忆......

我还在阅读有关核心转储和/ proc /

的文档

EDIT3:

我的技术总监建议下载可能会缓存然后写入磁盘上的整个文件,这可以解释内存使用情况。它并没有真正坚持一次性案例,因为我可以结束下载2个视频并在第三个视频结束时被杀,但我现在也在搜索它

EDIT4:

没关系最后一次编辑,我已经在大块写作了,这给了我们关于为什么记忆得到了吃的问题

2 个答案:

答案 0 :(得分:1)

首先,您需要确定OS杀死的系统进程。 然后我启用.core转储并进行分析。请检查ulimit -c命令和 得到这个的适当配置。当然,您需要为程序启用调试符号才能获得大部分内容。

如果您无法转储(没有足够的空间或任何其他限制),请考虑在客户端使用调试版本的进程进行远程调试。我认为你应该可以使用类似'远程GDB调试'之类的东西。

很可能你的过程在一些记忆分配上失败了,这很有可能解释你在哪里吃“记忆”,谁是有罪的,可能该怎么办。

希望这会有所帮助。

答案 1 :(得分:1)

您还可以使用/proc/文件系统(特别是/proc/self/statm/proc/$PID/statm等...),请参阅proc(5)以获取内存状态。

/proc/中还有其他有趣的伪文件,特别是/proc/meminfo/proc/$PID/maps等...