2016-11-11 2 views
0

У меня есть массив с именем globalArrayAllTrades, как вы видите ниже. Мне просто нравится наводить дату в новой копии массива. Поэтому я прокручиваю, создаю новый объект и добавляю его в новый массив - просто.Копировать массив -> переполнение стека или кучи?

После этого функция делает точно так, как ожидалось. НО, если массив содержит слишком много объектов, код выходит из строя с ошибкой «FATAL ERROR: CALL_AND_RETRY_LAST» - процесс выходит из памяти ».

Мой ноутбук имеет 8 ГБ памяти ... При сбое процесса NODEJS он использует около 1,5 ГБ и используется около 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; 
    } 
} 
+0

Это может ответить : http://stackoverflow.com/questions/7193959/memory-limit-in-node-js-and-chrome-v8 – Simon

+0

@Simon Этот вопрос составляет 5 лет. Один из ответов говорит о том, что ограничение памяти было удалено. – Barmar

+0

Что такое 'globalListAllTrades'? Похоже, вы используете его в качестве хранилища ключей (объекта), поэтому '.length = 0' вряд ли его пустят. – Bergi

ответ

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.

Другой способ поменять price, size и issell свойства в месте между парами элементов:

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

Я не знаю этих обозначений ... что такое торговля? В любом случае ... я думаю, что это решение будет использовать больше памяти, чем у Bergi's ... и что все еще не удается ... – PabloDK

+0

'trade' - это текущий элемент массива в цикле' .forEach(). – Barmar

+1

Я добавил еще одно решение, которое не выделяет никакой новой памяти, оно меняет местами свои свойства. – Barmar

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

+0

он не просто реверсирует массив. Он объединяет свойства объектов друг против друга в массиве. Посмотрите на 'objInv'. – Barmar

+0

Его НЕ ВСЕ свойства в массиве, которые я хочу изменить! Дата должна быть одинаковой - но цена, а остальная - должна быть «инвертирована». – PabloDK

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

Действительно приятно попробовать! Умная. Но я должен вас разочаровать. Он все еще падает. – PabloDK

+0

'globalArrayAllTrades/2' должно быть' globalArrayAllTrades.length/2' – Barmar

+0

Хм, это не сработает, потому что вы установили 'globalListAllTrades.length = 0' в строке ранее. Перед тем, как сделать это, вам нужно получить середина. – Barmar

Смежные вопросы