1

在我之前的问题(防止我的 node.js 应用程序被操作系统杀死)之后,我重新制作了我下载文件的方式。

简而言之,我需要下载一些视频文件(测试文件是 3 个视频,mp4,~3min),我一次下载它们,进程被杀死并且 dmesg 说(在 2 个下载完成后):

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

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

有什么方法可以查看我的代码的哪一部分出错,或者防止 linux 杀死我的进程?

顺便说一句,三个同时下载不是比一个消耗更多的内存吗?那么为什么我一个接一个地被杀死得更快呢?

该应用程序在树莓派上运行,没有 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);
}

编辑2:

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

heapTotal 在整个过程中缓慢增加,介于 20 000 000 和 25 000 000 之间,但有一些下降。heapUsed 正在迅速增加,当超过 6 000 000 时会定期下降到 ~2 000 000,在 ~12 000 000 时会出现一些峰值。

当进程被杀死时,最后一次打印是: rss: 428 707 840, heapTotal: 23 842 176, heapUsed: 5 854 164

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

我仍在阅读有关核心转储和 /proc/ 的文档

编辑3:

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

编辑4:

没关系上次编辑,我已经在逐块写了,这给了我们一个关于为什么内存被吃掉的问题

4

2 回答 2

1

首先,您需要确定操作系统杀死了哪些系统进程。然后我会启用.core转储并分析它。请检查ulimit -c命令和适当的配置以获取此信息。当然,您需要为您的程序启用调试符号才能获得大部分功能。

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

很可能你的进程在某些内存分配上失败了,这很有可能解释你在哪里“吃”了内存,谁有罪,可能该怎么办。

希望这会有所帮助。

于 2013-09-03T14:14:04.770 回答
1

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

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

于 2013-09-03T14:24:35.400 回答