2015-03-05 13 views
9

Quindi, ho sentito che si può presumibilmente fare tutti i fantasiosi giochi in tempo reale che utilizzano JS in questi giorni. E non sono un principiante, quindi dovrei provarci. Ha scritto del micro motore (incompleto) fisico con un po 'di rilevamento delle collisioni, tutto dolce. Un po 'troppo lento, si aspettava che GC si interrompesse. Quindi ho cercato di minimizzare qualsiasi allocazione, fino a quando non sono stato in grado di vedere tutto ciò che dovrebbe allocare memoria nel ciclo di gioco. Nessuna allocazione => nessuna pulizia, però. Ma ecco quello che ottengo: enter image description hereCosa sta mangiando la mia memoria? (L'edizione di utilizzo di SAW, JS mem)

Ora, questo non è affatto pulito. Così ho provato a rimuovere le mie cose dal loop di gioco in vari modi. Ancora SAW. Quindi no, vi presento il codice completo che genera questo:

<html><body><script> 
    function draw() { console.log(1); } 
    ;(function() { 
     function main(tFrame) { draw(); window.requestAnimationFrame(main); } 
     main(); 
    })(); 
</script></body></html> 

Incredibile? Bene, questo usa requestAnimationFrame in quanto sembra questo è quello che dovrebbe essere usato per prestazioni regolari. All'inizio ho provato l'intervallo impostato in questo modo:

<html><body><script> 
    function draw() { console.log(1); } 
    window.setInterval(draw, 0); 
</script></body></html> 

Esattamente la stessa cosa!

Questo sembra completamente inaccettabile, ma non ho idee su come fermare questo SAW. Ho guardato molto sul debug della memoria e cose del genere, mentre pensavo che il problema riguardasse le mie funzioni di disegno e aggiornamento. Ma questi ai frammenti, non hanno praticamente nulla, eppure producono quel ricordo di memoria. Forse è il mio browser? O è inevitabile, e JS è inutilizzabile per qualsiasi cosa in tempo reale? Mi piacerebbe credere che qualcuno sul web ne sappia qualcosa, perché ci sono molte persone che promettono meraviglie con JS. Cosa sto sbagliando in questi frammenti?

MODIFICA: tra l'altro la rimozione del registro della console non cambia nulla, nel caso in cui qualcuno pensi che questo sia il problema.

+0

Qualsiasi plug-in del browser in esecuzione in background? –

+0

Anche se qualcuno non può riprodurre questo, sarebbe interessante sentire la versione del sistema operativo e del browser. Sono in test Linux con Chromium 35.0.1916.153. – morphles

+0

@sixfingeredman no, solo un paio di schede aperte su bianco (beh, qualcosa è stato aperto ma io "backed"). Non che questo dovrebbe avere alcun effetto in quanto Chrome ha l'isolamento del processo, e spero che possa rilevare se plug-in o pagina sta usando CPU, e in particolare mem. – morphles

risposta

5

Analizziamo il codice un po ':

  • Si sta creando 3 funzioni all'avvio
  • si sta creando uno intero per ogni chiamata draw (60 + volte al secondo)
  • Si accede una volta al disegnare chiamata (che è super lento tra l'altro)

Ecco la performance di creare interi vs fare nulla contro la registrazione in JavaScript:

Creating Integers versus logging them

http://jsperf.com/creating-integers

siete comunque ragione. Dopo aver visitato una pagina about:blank e modificato un po 'il tuo codice, ho ricevuto alcuni dati interessanti.

Codice:

function draw() { 1; } 

function main(tFrame) { 
    draw(); 
    window.requestAnimationFrame(main); 
} 

main(); 

dati:

GC JS Saw

Questo grafico è oscillante tra 4.6MB e 5.2MB. In realtà non è un grosso problema. Liberare mezzo megabyte di memoria è molto veloce. Sfortunatamente, non c'è modo di evitarlo.Ho provato il seguente:

var j = 1; 

function draw() { j; } 

E mentre c'era meno spazzatura da raccogliere; GC funzionava ancora. Sul lato positivo sia in questo esempio e il precedente nostro codice viene eseguito a 60fps in ogni momento:

60fps... no logging

Morale della favola: la registrazione è costoso. È sempre costoso; javascript o no.

+0

La registrazione era effettivamente lì per assicurarsi che il codice fosse in loop, e non l'ho rimosso quando ho postato quest. Il mio problema principale è che, come si mostra anche quando si nota che rimane, succede anche a me quando il corpo della funzione è vuoto. Per quanto riguarda non è un problema, direi che lo è. Nel mio codice reale con la simulazione, è visibile che alcuni fotogrammi richiedono più tempo. Anche la cosa interessante è che le seghe di codice vuote richiedono circa 30 secondi, ma i denti di simulazione sono considerevolmente più corti forse anche al secondo. – morphles

+0

@morphles Non so esattamente cosa stai facendo durante il tuo ciclo. JS è single threaded e richiede più attenzione per ottenere buone prestazioni. Suggerimenti generali: 1) dovresti escogitare una strategia per non aggiornare durante il ciclo di rendering se possibile. Gestisco spesso eventi al di fuori del ciclo e li faccio modificare i dati. In questo modo il ciclo di rendering rimane un percorso di codice di sola lettura. 2) semplificare la scena in qualche modo (abbattimento/livello di dettaglio/rtrees) questo ti permette di elaborare solo alcune parti dello schermo. 3) Se hai assolutamente bisogno di più potenza di cavalli, considera i web worker. 4) matrici digitate. Stai usando webgl? – Parris

+0

sì, forse cercherò di spostare gli aggiornamenti nel timeout impostato e di lasciare il disegno su animframe. 2, per ora schiene è molto semplice, anche un paio di palline che rimbalzano di linee sembrano stesse 300 palle (il che è strano, e questo mi fa sospettare che GC più di ogni altra cosa). Per ora dubito che gli array digitati mi daranno molto (ancora 300 contro 3 palle, il ritardo sembra lo stesso). Non sto usando webgl, e non voglio davvero usarlo. – morphles

Problemi correlati