11

Ich habe eine App, die häufig binäre Nachrichten über einen WebSocket (mindestens einmal pro Rahmen) empfängt und die Daten plottet, mit Canvas/Webgl. Ich habe bemerkt, dass ich ein ziemlich gutes Sägezahngedächtnisprofil habe; viele kurzlebige Datenbrocken. enter image description hereWebSocket häufige onmessage zero-copy

Das überrascht mich nicht, da ich ein Objekt aus onmessage, mindestens einmal alle 16 ms empfangen, die zum Zeichnen und dann dereferenziert verwendet wird.

Meine Frage ist: Gibt es irgendwelche Tipps zur Vermeidung/Minimierung? Basierend auf dem WebSocket API scheint es keine Alternative zu geben, dass bei jedem Socket-Empfangsaufruf neuer Speicher zugewiesen wird. In einer anderen Sprache/Umgebung würde ich etwas Speicher vorgeben und in diesen Puffer aufnehmen, um zu vermeiden, dass ständig Speicher für kurzlebige Objekte zugewiesen werden, aber ich kann mir keinen offensichtlichen Weg vorstellen, dies in JavaScript im Browser zu erreichen.

Als Referenz, hier ist meine Frames Ansicht.

enter image description here

Ich weiß nicht, ob das Leerlaufzeit Garbage Collection ist? Alle dev-tools Ninja Einblicke würden sehr geschätzt werden.

+0

in JS Haben Sie bekommen jedes Codebeispiel finden können? habe etwas angefangen? eine Geige? – Anonymous0day

+1

Ich habe das gleiche Problem streaming Sensor Datum von meinem Raspberry Pi über WebSockets. Ich fürchte, es gibt und wird keine Möglichkeit geben, die Speicherzuweisung von WebSockets in Javascript zu stören. Meine Forschung hat keine Ergebnisse gebracht. – windm

+0

Was möchten Sie erreichen? Wie lange läuft das Programm und wie wichtig ist konsistente, langlebige Leistung? Einen kleinen Code oder ein Codebeispiel zu sehen wäre großartig. –

Antwort

1

nicht sicher, ob ich das Problem verstanden, aber Sie können eine globale Array wie in einer anderen Sprache erklären und sie als Ringpuffer verwendet wird, zum Beispiel:

var buffer = []; 
var bufferLength = 1000; 
var start = 0; 
var end = 0; 
var content = 0; 

socket.onmessage(function(msg) { //msg allocated 
    end %= bufferLength; 
    if (end == start && content != 0) 
     console.log("Buffer is full"); 
    else { 
     content++; 
     buffer[end++] = msg; //reference to msg saved so it's not destroyed at the end of the callback 
    } 
}); 

function getNext() { 
    start %= bufferLength; 
    if (start == end && content == 0) 
     console.log("Buffer is empty"); 
    else { 
     content--; 
     return buffer[start++]; // returns reference to next msg 
    } 
} 

Edit: Ich veränderte die Antwort mehr zu sein Löschen über den Speicherzyklus:

JS reserviert Speicher für die empfangene Nachricht auf Websockets und erstellt einen Verweis darauf msg, die Ihnen als ein Parameter in dem Rückruf für onmessage definiert wird.

Hinweis JS GC wird nur dieses Speicherstück zerstören, wenn es im Code nicht mehr referenziert wird.

Ich speichere diesen Verweis in einem Puffer, so dass der Wert nicht zerstört wird, wenn der Rückruf ausgeführt wird, und Sie später mit darauf zugreifen können. Sie müssen keinen neuen Speicher zuweisen, da JS dies für Sie erledigt hat.

Wenn Sie eine andere Kopie von msg klonen oder erstellen möchten, gibt es verschiedene Optionen. Eine einfache Möglichkeit, dass Ihnen ein unrunde JSON-Objekt wäre klonen kann:

var newJSON = JSON.parse(JSON.stringify(msg)); 

Sie weitere Informationen über die Speicherzuordnung in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management

+0

Das beantwortet meine Frage nicht, die speziell in Bezug auf "Neuer Speicher, der jedem Socket-Empfangsanruf zugewiesen wird". – sethro

+0

Ich bin speziell mit dem Speicher betroffen, der für das an 'onmessage' übergebene Objekt zugewiesen wurde: 'msg'. Ich denke, du verstehst meine Frage falsch. Ich frage nach einer Möglichkeit, einen Puffer vorab zuzuweisen, den der WebSocket oder vielleicht eine andere API verwenden wird, um vom zugrunde liegenden Socket zu empfangen. – sethro

+1

Ok, ich verstehe dein Problem jetzt. Ich glaube nicht, dass Sie mit JS etwas dagegen tun können. Sie können möglicherweise einen Teil der Gesamtverzögerung verringern, indem Sie den Rasterisierungsfilter ohne Kopie in Chrom-Chrom aktivieren: // flags/# enable-zero-copy, so dass es in webgl schneller gerendert wird. Wenn Ihr Problem mit dem Speicherzugriff besteht, können Sie mit der Anzahl/Größe der vom Server gesendeten Pakete spielen, weniger/größere Pakete reduzieren die Anzahl der Operationen. –

Verwandte Themen