2010-10-31 8 views
26

Sfondo: Attualmente sto lavorando su un sito intranet che fa uso della libreria MochaUI (lavoro dalla virtual desktop demo). Sto usando Mootools 1.2.4 e MochaUI 0.9.7. Le finestre che vengono aperte nella mia implementazione "desktop virtuale" caricano il loro contenuto tramite iframe. Alcune delle pagine caricate sono piuttosto pesanti in termini di css e scripting, quindi è importante che gli oggetti Window siano adeguatamente raccolti quando l'utente chiude una finestra. Questo è apparentemente curato dalla biblioteca (fa un buon lavoro quando si utilizza Firefox).Chrome non riesce a liberare la memoria, raccolta dei rifiuti non si verifica come previsto (biblioteca Mootools/MochaUI)

Aggiornamento La domanda originariamente inviata era diventata troppo lunga per le successive modifiche/aggiornamenti. Il titolo non era più preciso, quindi ho cambiato anche quello. Inoltre, vedi la mia risposta qui sotto per una soluzione parziale.

Ecco i punti essenziali:

  1. Chrome goofs up in questo modo:

    • Chrome non riesce a liberare la memoria allocata per oggetti finestra MochaUI quando sono chiusi. Invece, l'utilizzo della memoria di Chrome si blocca (letteralmente) al livello raggiunto dopo che la finestra ha completato il caricamento del suo contenuto iframe, impostando un limite inferiore sull'utilizzo della memoria fino a quando la pagina non viene aggiornata.
    • La memoria utilizzata dal processo continua ad aumentare con le successive aperture/chiusure delle finestre. Alla fine, viene raggiunto un certo tipo di cap, e l'utilizzo della memoria smette di arrampicarsi come ripida/inizia a oscillare invece di saltare drasticamente.
    • Questo problema è più evidente quando le finestre in questione caricano contenuti iframe abbastanza pesanti (in termini di memoria). La finestra che sto usando per tutti gli scopi di test carica una pagina di 580 kb (senza cache) nel suo iframe.
  2. Stranamente, la raccolta dei rifiuti previsto fa avvenire, quando

    • il browser viene successivamente minimizzato
    • un'altra scheda si apre nella stessa finestra del browser
    • un La cronologia della memoria viene registrata in Strumenti per sviluppatori. (opzione comedy)
    • Questo comportamento suggerisce qualche possibile approccio alla soluzione n. 1?
+5

domanda molto interessante e buona spiegazione. Non sono esattamente sicuro di quale sia il colpevole, anche se ti avvertirò che c'è una possibilità che non ci sarà una soluzione. O se ce n'è uno, non è facile. Google ha un approccio molto pigro alla programmazione. Anche se Chrome sembra caricare più velocemente e consumare meno memoria di tutti i principali browser, è pieno di bug che non avrei mai immaginato in Firefox o Opera. Lo stesso con Android contro iOS. – stevendesu

+0

Ho pubblicato una versione molto dettagliata/lunga di questa domanda nel forum di assistenza per Chrome Webmaster di Google e non ho ricevuto risposta, quindi questa volta ho deciso di renderlo più concreto! Sono d'accordo che questo sembra un bug (o un capriccio di come Chrome determina quali oggetti devono essere raccolti da garbage). È come se ci fosse un livello più pesante di garbage collection che si verifica quando Chrome è ridotto a icona e gli oggetti della mia finestra non sono completamente inutili secondo gli standard di Chrome, forse. Grazie per il commento! – freenatec

+4

@steven_desu: Google non solo ha adottato un approccio pigro alla programmazione, ma sembra anche estremamente apatico nei confronti di qualsiasi tipo di lamentele o problemi che i suoi utenti hanno riscontrato. –

risposta

6

io non sono sicuro se questo è stato testato in Windows, ma se è così tenere a mente che ogni volta che si riduce a icona una finestra in Windows si sposta tutti i dati per il file di paging. Quando si apre nuovamente la finestra, i blocchi di memoria non verranno spostati indietro a meno che il programma non tenti di accedervi, e quindi qualsiasi garbage rimanga nel file di paging ma non viene effettivamente raccolto.

Se lo avessi automatizzato, non solo rallenterebbe il programma, ma non aiuterebbe nemmeno con problemi di memoria.

il seguente URL per un po 'più di informazioni

https://micksmix.wordpress.com/2010/01/08/why-does-task-manager-show-an-applications-memory-usage-drop-after-minimizing-it-to-the-the-taskbar/

+0

Tutte le macchine sulla intranet che utilizzeranno il sito eseguiranno Windows XP, credo. Non avevo considerato questo problema con il file di paging, sebbene l'automazione/ingannando Chrome al suo stato Minimizzato (in qualche modo, a qualsiasi effetto) fosse un concetto a lunga distanza ...Idealmente, troverei un modo per cambiare il mio codice javascript in modo che Chrome riconosca gli oggetti da raccogliere come garbage. – freenatec

+1

Hai provato a impostare le variabili/oggetti su null una volta che hai finito con loro? – William

+0

Per quanto riguarda le funzioni della libreria che gestiscono il comportamento di chiusura della finestra, sembra che imposti tutti gli oggetti rilevanti su null quando si chiude una finestra. Il contenuto caricato in Windows (negli iframe) è più il mio codice, ed è un po 'disordinato e probabilmente contribuisce alle perdite ... tuttavia, dovrei notare che Firefox libera chiaramente la memoria quando Windows si chiude (per un motivo di 3-5 MB in circa 5 secondi). L'utilizzo della memoria del processo Chrome pertinente, d'altra parte, rimane statico quando le finestre sono chiuse e l'unica cosa che lo fa diminuire è la riduzione al minimo del browser. – freenatec

3

Aggiornamento
le seguenti modifiche alla funzione MochaUI closingJobs sono un miglioramento grande su quello che ho già postato qui. La modifica principale è ora che l'evento onunload dell'iframe viene chiamato manualmente cambiando la proprietà src, invece di essere attivato quando il metodo windowEl.destroy rimuove l'iframe dal DOM. (ho avuto l'idea da here).

Se si desidera utilizzare questo codice, è sufficiente eliminare la funzione closingJobs esistente e copiare il codice incollarlo al suo posto. Lo dovrebbe funzionare con entrambi 0.9.7 e 0.9.8 MochaUI e Mootools 1.2.4 o 1.3.


closingJobs: function(windowEl){   
    windowEl.setStyle('visibility', 'hidden'); 
    var instances = MUI.Windows.instances; 
    var instance_id = windowEl.id 
    var cleanup_delay = 50; 

    /* 
    Reset canvases with width/height = 0. 
    This pretty reliably frees a few hundred Kb of 
    memory in chrome. 
    */   
    instances[instance_id].canvasControlsEl.width = 0; 
    instances[instance_id].canvasControlsEl.height = 0; 
    instances[instance_id].canvasEl.width = 0; 
    instances[instance_id].canvasEl.height = 0;   

    if(instances[instance_id].options.loadMethod == 'iframe') 
    { 
/* 
The following line determines how long to delay the execution of 
the windowEl.destroy function. The line below gives 10 milliseconds 
per DOM element in the iframe's document. 
You could probably do just as well with a hard-coded value. 
*/   
     cleanup_delay = instances[instance_id].iframeEl.contentDocument.getElementsByTagName("*").length * 10;    

/* 
Set the Browser property in the iframe's window to Internet Explorer. 
This causes Mootools to run its purge function, which iterates over 
all the iframe document's DOM elements, removing events/attributes etc. 
Assuming you have mootools included in the iframe content.  
*/ 
     if(instances[instance_id].iframeEl.contentDocument.defaultView.MooTools) 
     {   
      if(instances[instance_id].iframeEl.contentDocument.defaultView.MooTools.version.contains("1.3"))     
       instances[instance_id].iframeEl.contentDocument.defaultView.Browser.ie = true; 
      else   
       instances[instance_id].iframeEl.contentDocument.defaultView.Browser.Engine.trident = true; 
     }     

     instances[instance_id].iframeEl.src = "javascript:false"; 
    }  

    MUI.cleanWindow.delay(cleanup_delay, null, windowEl);  
}, 

cleanWindow: function(windowEl) 
{        
    var instances = MUI.Windows.instances; 
    var instance_id = windowEl.id 
    if (Browser.ie){ 
     windowEl.dispose(); 
    } 
    else { 
     windowEl.destroy(); 
    }  
    instances[instance_id].fireEvent('onCloseComplete'); 

/* 
Changed - Only execute getWindowWithHighestZindex() and focusWindow() 
functions if there will actually be open windows after the 
current one closes. 
*/ 
    if (instances[instance_id].options.type != 'notification' && instances.__count__ > 1){ 
     var newFocus = MUI.getWindowWithHighestZindex(); 
     MUI.focusWindow(newFocus); 
    }  
    if (this.loadingWorkspace) this.windowUnload(); 
    if (MUI.Dock && $(MUI.options.dock) && instances[instance_id].options.type == 'window'){ 
     var currentButton = $(instances[instance_id].options.id + '_dockTab'); 
     if (currentButton != null){ 
      MUI.Dock.dockSortables.removeItems(currentButton).destroy(); 
      currentButton = null; //Is this necessary? 
     }   
     MUI.Desktop.setDesktopSize(); 
    } 

    //Changed - moved this to the end of the function. 
    delete instances[instance_id]; 
} 
+1

anche, quale versione di mootools è in uso. mootools 1.3 ha un elemento element.prototype.destroy un po 'semplificato in questo modo: http://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L677 rispetto al vecchio http://github.com/mootools/mootools-core/blob/1.2x/Source/Element/Element.js#L579 che va alla strana funzione 'clean()' qui sopra. –

+0

1.2.4. Sto vedendo le stesse cose accadere con 1.3 (con il build 0.9.7 MochaUI, cioè). Nel mio test ho usato il livello di compatibilità, anche se non sono sicuro se questo è un fattore qui. La correzione che suggerisco sopra ha lo stesso effetto sul comportamento della memoria di Chrome con 1.3 come con 1.2.4. Tutto ciò potrebbe cambiare, però: basandomi sul tuo primo commento, ho spiato un po 'di più nel github di moka ui - ero totalmente inconsapevole che il ramo 0.9.8 avesse un'attività così recente! Grazie per averlo portato alla mia attenzione. – freenatec

+0

nessun problema! il vecchio mochaui è stato ... difficile da lavorare. Sto ancora supportando la mia filiale a causa dell'enorme numero di correzioni che ho dovuto implementare e ora usare 0.9.8 o 1.0 sarà quasi impossibile! Oh bene! –