11

Ho un'app che riceve frequentemente messaggi binari su una WebSocket (almeno una volta per frame) e traccia i dati, usando canvas/webgl. Ho notato che ho un profilo di memoria del dente di sega piuttosto buono; molti pezzi di dati di breve durata. enter image description hereWebSocket onmessage frequente zero-copy

Questo non mi sorprende dal momento che sto ricevendo un oggetto da onmessage, almeno una volta ogni 16 ms, che viene utilizzato per il disegno e poi de-reference.

La mia domanda è: ci sono suggerimenti per evitare/minimizzare questo? In base allo WebSocket API, non sembra essere un'alternativa all'aver ricevuto una nuova memoria allocata su ogni chiamata di ricezione socket. In un'altra lingua/ambiente, pre-allocare un po 'di memoria e ricevere in quel buffer, per evitare di allocare costantemente memoria per oggetti di breve durata, ma non riesco a pensare ad alcun modo ovvio per ottenere ciò in JavaScript nel browser.

Per riferimento, ecco la vista Frames.

enter image description here

Non so se questo tempo di inattività è garbage collection? Qualsiasi intuizione ninja degli strumenti di sviluppo sarebbe molto apprezzata.

+0

Avete qualche esempio di codice? hai iniziato qualcosa? un violino? – Anonymous0day

+1

Ho lo stesso problema con la data del sensore di streaming dal mio raspberry pi su WebSockets. Temo che non ci sia e non sarà in alcun modo possibile interferire con l'allocazione della memoria di WebSockets in javascript. La mia ricerca non ha portato alcun risultato. – windm

+0

Cosa speri di ottenere? Quanto dura il programma e quanto è importante una prestazione costante e di lunga durata? Vedere un piccolo codice o un esempio di codice sarebbe fantastico –

risposta

1

Non sono sicuro se ho capito il tuo problema, ma è possibile dichiarare una matrice globale come in qualsiasi altra lingua e usarlo come un buffer circolare, ad esempio:

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: ho modificato la risposta di essere più chiaro sul ciclo di memoria:

JS allocherà memoria per il messaggio ricevuto su websockets e creerà un riferimento ad esso chiamato msg che verrà assegnato come param nel callback definito per onmessage.

Nota JS GC distruggerà solo quel pezzo di memoria quando non viene più fatto riferimento nel codice.

Quello che faccio sopra è il salvataggio di quel riferimento all'interno di un buffer in modo che il valore non venga distrutto quando il callback è terminato ed è possibile accedervi successivamente usando getNext. Non è necessario allocare nuova memoria perché JS l'ha fatto per te.

Nel caso in cui si voglia clonare o creare una copia diversa di msg, ci sono alcune opzioni differenti. Un semplice opzione che vi permetterà di clonare un oggetto JSON non circolare sarebbe:

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

È possibile trovare maggiori informazioni sulla allocazione di memoria a JS in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management

+0

Questo non risponde alla mia domanda, che riguarda specificamente "Nuova memoria allocata su ogni socket riceve una chiamata". – sethro

+0

Mi interessa in particolare la memoria allocata per l'oggetto passato a 'onmessage':' msg'. Penso che tu abbia frainteso la mia domanda. Sto chiedendo un modo per pre-allocare un buffer che il WebSocket o forse qualche altra API utilizzerà per ricevere dal socket sottostante. – sethro

+1

Ok, ho capito il tuo problema ora. Non penso che tu possa fare qualcosa a riguardo usando JS. Potresti essere in grado di mitigare parte del ritardo totale che abilita il rasterizzatore a zero copie in chrome chrome: // flags/# enable-zero-copy in modo da renderlo più veloce in webgl. Inoltre, dato il tuo problema riguarda l'accesso alla memoria, puoi giocare con il numero/dimensione dei pacchetti inviati dal server, pacchetti meno/più grandi ridurranno il numero di operazioni. –

Problemi correlati