复制数组——>堆栈或堆溢出

Copy array --> stack or heap overflow?

本文关键字:溢出 堆栈 复制数组      更新时间:2023-09-26

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

则函数完全按照预期执行。但是,如果数组包含太多对象,代码将失败,并显示"致命错误:CALL_AND_RETRY_LAST Allocation failed - process out of memory"。

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

我确实运行NODEJS应用程序的参数:--max_old_space_size=5000通常修复一切。但不是这一个,我已经尝试了许多不同的方法来编码相同的功能-但每一次-它失败了…除非原始数组更小。

如何解决这个问题?

 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;
     }
 }

你可以节省一些内存通过使原始只包含属性,你需要反转,而不是整个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

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

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;
}

你考虑过这样做吗?

// 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

我建议避免复制这个数组:

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;
     }
 }