复制数组 - >堆栈或堆溢出?

时间:2016-11-11 00:01:44

标签: javascript arrays node.js heap-memory

我有一个名为globalArrayAllTrades的数组,如下所示。我只想在数组的新副本中反转日期。所以我循环,创建一个新对象并将其添加到新数组 - 简单。

然后功能完全按预期进行。但是,如果数组包含太多对象,则代码将失败并出现“致命错误:CALL_AND_RETRY_LAST分配失败 - 处理内存不足”。

我的笔记本电脑有8 GB内存......当NODEJS进程崩溃时,它使用大约1.5 GB,并且使用了大约70%的可用内存。

我使用参数--max_old_space_size=5000运行NODEJS应用程序,它通常会修复所有内容。但不是这个,我已经尝试了许多不同的方法来编写相同的函数 - 但每次都失败了......除非原始数组更小。

如何解决此问题?

 function invertTrades(){

     var original = globalArrayAllTrades.slice();

     globalArrayAllTrades.length = 0;
     globalListAllTrades.length = 0;

     for(var i = 0; i < original.length; i++){

         var objS = original[i];
         var objE = original[original.length-1-i];
         var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);

         globalArrayAllTrades.push(objInv);

         globalListAllTrades[objInv.matchdate] = objInv;
     }
 }

3 个答案:

答案 0 :(得分:1)

您可以通过使原始只包含需要反转的属性而不是整个TradePoint对象来保存一些内存。然后,您不需要构建新的TradePoint对象,您可以在适当的位置修改它们。

var original = globalArrayAllTrades.map(function(trade) {
    return {
        trade.price,
        trade.size,
        trade.issell
    };
}).reverse();
globalArrayAllTrades.forEach(function(trade, i) {
    trade.price = original[i].price;
    trade.size = original[i].size;
    trade.issell = original[i].issell;
});

由于所有对象都已就地修改,因此无需更新globalListAllTrades

另一种方法是在元素对之间交换pricesizeissell属性:

var midpoint = Math.floor(globalArrayAllTrade.length/2);
for (var i = 0; i < midpoint; i++) {
    var objS = globalArrayAllTrades[i];
    var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];

    var temp = objS.price;
    objS.price = objE.price;
    objE.price = temp;

    temp = objS.size;
    objS.size = objE.size;
    objE.size = temp;

    temp = objS.issell;
    objS.issell = objE.issell;
    objE.issell = temp;
}

答案 1 :(得分:0)

你考虑过这样做吗?

// Copy array and then reverse it
var newArray = [].concat(original).reverse();

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse

答案 2 :(得分:0)

我建议避免复制该数组:

function getInverse(i) {
    var objS = globalArrayAllTrades[i];
    var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
    var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
    globalListAllTrades[objInv.matchdate] = objInv;
    return objInv;
}
function invertTrades(){
     globalListAllTrades.length = 0;
     for (var i = 0, l = Math.floor(globalArrayAllTrades.length/2); i < l; i++) {
         var j = globalArrayAllTrades.length-1-i;
         var a = getInverse(i);
         var b = getInverse(j);
         globalArrayAllTrades[i] = a;
         globalArrayAllTrades[j] = b;
     }
 }