2016-11-11 3 views
0

Ich habe ein Array namens globalArrayAllTrades, wie Sie unten sehen. Ich möchte einfach das Datum in eine neue Kopie des Arrays INVERTIEREN. Also ich durchschlinge, ein neues Objekt erstellen und es dem neuen Array hinzufügen - einfach.Array kopieren -> Stack- oder Heap-Überlauf?

Dann funktioniert die Funktion genau wie erwartet. ABER wenn das Array zu viele Objekte enthält, schlägt der Code mit einem "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - Prozess nicht genügend Arbeitsspeicher".

Mein Laptop hat 8 GB Speicher ... Wenn der NODEJS-Prozess abstürzt, verwendet es etwa 1,5 GB und etwa 70% der gesamten verfügbaren Speichermenge wird verwendet.

Ich führe die NODEJS App mit dem Parameter: --max_old_space_size=5000, die normalerweise alles regelt. Aber nicht dieses und ich habe viele verschiedene Möglichkeiten versucht, um die gleiche Funktion zu programmieren - aber jedes Mal - es scheitert ... es sei denn, das ursprüngliche Array ist kleiner.

Wie kann ich dieses Problem beheben?

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

Diese Antwort kann : http://stackoverflow.com/questions/7193959/memory-limit-in-node-js-and-chrome-v8 – Simon

+0

@Simon Diese Frage ist 5 Jahre alt. Eine der Antworten besagt, dass das Speicherlimit entfernt wurde. – Barmar

+0

Was ist 'globalListAllTrades'? Es scheint, dass Sie es als Schlüssel-Wert-Speicher (Objekt) verwenden, also wird '.length = 0' es kaum leeren. – Bergi

Antwort

1

Sie etwas Speicher Original enthalten sparen können, indem sie nur die Eigenschaften, die Sie umkehren müssen, nicht das ganze TradePoint Objekt. Dann müssen Sie keine neuen TradePoint Objekte erstellen, Sie können sie an Ort und Stelle ändern.

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

Und da alle Objekte an Ort und Stelle verändert wurden, gibt es keine Notwendigkeit globalListAllTrades zu aktualisieren.

Eine andere Möglichkeit ist es, die price, size und issell Eigenschaften zwischen den Paaren von Elementen zu tauschen:

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

Ich kenne diese Notation nicht ... was ist Handel? Wie auch immer ... ich denke, diese Lösung wird mehr Speicher als Bergi verwenden ... und das schlägt immer noch fehl ... – PabloDK

+0

'trade' ist das aktuelle Element des Arrays in der' .forEach() 'Schleife. – Barmar

+1

Ich habe eine andere Lösung hinzugefügt, die keinen neuen Speicher zuweist, sie tauscht die Eigenschaften aus. – Barmar

0

Haben Sie darüber nachgedacht?

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

er nicht nur das Array umzukehren. Er kombiniert Eigenschaften der Objekte, die sich im Array gegenüberliegen. Schau dir 'objInv' an. – Barmar

+0

Es sind nicht alle Eigenschaften im Array, die ich gerne ändern würde! Das Datum muss gleich sein - aber der Preis und der Rest müssen "invertiert" sein. – PabloDK

0

würde ich vermeiden lassen vermuten, dass Array zu kopieren:

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

Wirklich netter Versuch! Clever. Aber ich muss dich enttäuschen. Es stürzt immer noch ab. – PabloDK

+0

'globalArrayAllTrades/2' sollte 'globalArrayAllTrades.length/2' sein. – Barmar

+0

Hmm, das wird nicht funktionieren, weil Sie' globalListAllTrades.length = 0' in der Zeile davor gesetzt haben. Sie müssen den Mittelpunkt erreichen, bevor Sie das tun. – Barmar