使用nodejs调试堆栈溢出异常

时间:2014-02-13 11:02:33

标签: node.js

我正在使用nodejs解析大量文件。在我的过程中,我正在解析音频文件,视频文件,而不是其他文件。

解析文件的功能如下所示:

/**
* @param arr : array of files objects (path, ext, previous directory)
* @param cb : the callback when every object is parsed, 
*             objects are then throwed in a database
* @param others : the array beeing populated by matching objects
**/
var parseOthers = function(arr, cb, others) {

    others = others === undefined ? [] : others;

    if(arr.length == 0)
        return cb(others); //should be a nextTick ?

    var e = arr.shift();

    //do some tests on the element and add it
    others.push(e);
    //Then call next tested callImediate and nextTick according
    //to another stackoverflow questions with no success
    return parseOthers(arr, cb, others);
});

Full code here(关心它一团糟)

现在有大约3565个文件(不是那么多),脚本会捕获“RangeError:超出最大调用堆栈大小”异常,没有任何痕迹。

我尝试了什么:

  • 我尝试使用node-inspectornode debug script调试它,但是它永远不会挂起,好像它在没有调试的情况下运行(调试会增加堆栈吗?)。
  • 我尝试使用process.on('uncaughtException')来捕获异常但没有成功。

我没有内存泄漏。

我怎样才能找到异常追踪?

修改1

增加--stack_size接缝效果非常好。 是否还有另一种方法可以阻止这种情况?

(约1300年)

修改2

根据:

$ node --v8-options | grep -B0 -A1 stack_size

默认堆栈大小(以KB为单位)为984。

编辑3

还有一些解释:

  • 我从不读这类文件
  • 我在一个路径数组上工作,我不会递归地解析文件夹
  • 我正在查看路径并检查它是否已存储在数据库中

我的猜测是填充的数组对于nodejs变得很大,但是内存看起来很好而且很奇怪......

2 个答案:

答案 0 :(得分:4)

大多数Stackoverflow情况都不容易或有时可以调试。即使您对问题进行调试,也可能找不到触发器。

但我可以建议您轻松共享任务负载(包括队列管理):

JXcore(Node.JS上的多线程分支)适合您的情况。只需创建一个任务池并设置一次处理1个文件的任务方法。它将逐个管理你的队列1多线程。

var myTask = function ( args here )
{
    logic here
}

for(var i=0;i<LIST_OF_THE_FILES;i++)
    jxcore.tasks.addTask( myTask, paramshere, optional callback ...    

如果逻辑定义超出单个方法的范围,则为OR;

var myTask = function ( args here )
{
    require('mytasketc.js').handleTask(args here);
}

for(var i=0;i<LIST_OF_THE_FILES;i++)
    jxcore.tasks.addTask( myTask, paramshere, optional callback ... 

<强>说明

每个线程都有自己的V8内存限制。

线程之间的上下文是分开的

确保任务方法最终关闭文件

链接

您可以在multithreaded Javascript tasks

上找到更多信息

答案 1 :(得分:1)

由于递归,您收到此错误。重新格式化你的代码不要使用它,特别是因为这种代码的安静真的不需要它。以下是APPROXIMATE示例,向您展示如何做得更好:

var parseElems = function(arr, cb) {
    var result = [];
    arr.forEach(function (el) {
         //do some tests on the element (el)
         result.push(el);
    });

    cb(result);
});