2010-10-31 7 views
26

Hintergrund: Ich bin zur Zeit auf einer Intranet-Site arbeiten, die Nutzung der MochaUI Bibliothek (Arbeits vom virtual desktop demo) macht. Ich benutze Mootools 1.2.4 und MochaUI 0.9.7. Die Fenster, die in meiner "virtual desktop" -Implementierung geöffnet sind, laden ihren Inhalt über iFrames. Einige der geladenen Seiten sind ziemlich umfangreich in Bezug auf CSS und Scripting. Daher ist es wichtig, dass Window-Objekte beim Öffnen eines Fensters mit einem Garbage Collection-Filter versehen werden. Dies wird angeblich von der Bibliothek erledigt (es macht einen guten Job, wenn man Firefox benutzt).Chrome versagen Speicher frei, Müllabfuhr tritt nicht wie erwartet (Mootools/MochaUI Bibliothek)

Aktualisierung Die ursprünglich gepostete Frage war von nachfolgenden Bearbeitungen/Aktualisierungen übermäßig lang geworden. Der Titel war nicht mehr korrekt, also habe ich das auch geändert. Siehe auch meine Antwort unten für eine Teillösung.

Hier sind die wesentlichen Punkte:

  1. Chrome goofs wie so hoch:

    • Chrome versagt Speicher für Fensterobjekte MochaUI zugewiesen oben freizugeben, wenn sie geschlossen sind. Stattdessen wird die Speicherauslastung von Chrome auf der Ebene eingefroren, die erreicht wird, nachdem das Fenster den Iframe-Inhalt geladen hat. Dabei wird eine Untergrenze für die Speichernutzung festgelegt, bis die Seite aktualisiert wird.
    • Der vom Prozess verwendete Speicher wird mit nachfolgenden Fensteröffnungen weiter vergrößert. Irgendwann wird irgendeine Art von Cap erreicht, und die Speicherbelegung hört auf zu steigen, wenn sie steil anschwingt oder zu oszillieren beginnt, anstatt dramatisch aufzuspringen.
    • Dieses Problem tritt am deutlichsten auf, wenn die fraglichen Fenster ziemlich heftigen (Speicher-Iframe) Inhalt laden. Das Fenster, das ich für alle Testzwecke verwende, lädt eine 580-kb-Seite (nicht zwischengespeichert) in seinem iframe.
  2. Merkwürdigerweise die erwartete Garbage Collection tut stattfinden, wenn

    • der Browser anschließend
    • weitere Registerkarte im selben Browserfenster
    • geöffnet wird minimiert wird
    • ein Die Speicherzeitachse wird in den Entwicklertools aufgezeichnet. (Komödie Option)
    • Gibt dieses Verhalten mögliche Ansätze zur Lösung von # 1?
+5

Sehr interessante Frage und gute Erklärung. Ich bin mir nicht ganz sicher, was der Schuldige ist, obwohl ich euch warnen werde, dass es eine Chance gibt, dass es keine Lösung geben wird. Oder wenn es einen gibt, keinen leichten. Google geht beim Programmieren sehr faul vor. Obwohl Chrome am schnellsten zu laden scheint und den geringsten Speicher jedes großen Browsers verwendet, ist es voller Bugs, von denen ich in Firefox oder Opera nicht träumen würde. Gleiches gilt für Android und iOS. – stevendesu

+0

Ich habe eine sehr ausführliche/langweilige Version dieser Frage im Google Chrome Webmaster-Hilfeforum gepostet und keine Antwort erhalten. Deshalb habe ich mich diesmal dafür entschieden, es auf den Punkt zu bringen! Ich stimme zu, dass dies wie ein Fehler aussieht (oder eine Eigenart davon, wie Chrome bestimmt, welche Objekte als Müll erfasst werden). Es ist, als gäbe es eine größere Menge an Garbage Collection, die auftritt, wenn Chrome minimiert wird, und meine Fensterobjekte sind vielleicht nicht völlig unbrauchbar nach den Standards von Chrome. Danke für den Kommentar! – freenatec

+4

@steven_desu: Nicht nur, dass Google einen faulen Programmieransatz wählt, es scheint auch ziemlich apathisch zu sein für jegliche Art von Beschwerden oder Problemen, die seine Benutzer auftauchen. –

Antwort

6

Ich bin mir nicht sicher, ob dies in Windows getestet wurde, aber wenn so denken Sie daran, dass, wenn Sie ein Fenster in Fenster minimieren, ist es, alle Daten zu der Auslagerungsdatei bewegt. Wenn das Fenster erneut geöffnet wird, werden die Speicherblöcke nicht zurück verschoben, es sei denn, das Programm versucht, auf sie zuzugreifen, und somit bleibt der Müll in der Auslagerungsdatei, wird aber nicht tatsächlich gesammelt.

Wenn Sie es automatisieren, würde es nicht nur das Programm verlangsamen, es würde auch nicht mit irgendwelchen Speicherproblemen helfen.

siehe die folgende URL für ein bisschen mehr Infos

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

Alle Computer im Intranet, die die Website verwenden, führen Windows XP aus, glaube ich. Ich hatte dieses Problem mit der Auslagerungsdatei nicht in Betracht gezogen, obwohl das Automatisieren/Auslösen von Chrome in seinen minimierten Zustand (irgendwie, egal welchen Effekt) ein Langzeitkonzept war ...Im Idealfall würde ich einen Weg finden, meinen JavaScript-Code so zu ändern, dass Chrome die Objekte wie üblich als Garbage Collection erkennt. – freenatec

+1

Haben Sie versucht, die Variablen/Objekte auf Null zu setzen, wenn Sie fertig sind? – William

+0

Soweit ich die Funktionen der Bibliothek begreife, die das Verhalten beim Schließen von Fenstern behandeln, scheint es, dass alle relevanten Objekte beim Schließen eines Fensters auf null gesetzt werden. Der in den Fenstern (in iframes) geladene Inhalt ist mehr mein eigener Code, und er ist etwas unordentlich und trägt wahrscheinlich zu Lecks bei ... aber ich sollte beachten, dass Firefox beim Schließen von Fenstern eindeutig Speicherplatz freigibt (im Bereich von 3-5 MB über ungefähr 5 Sekunden). Die Speicherauslastung des relevanten Chrome-Prozesses bleibt dagegen beim Schließen von Fenstern statisch und verringert nur den Browser. – freenatec

3

aktualisieren
die folgenden Änderungen an der MochaUI closingJobs Funktion sind eine große Verbesserung gegenüber, was ich vorher hier gepostet. Die wichtigste Änderung ist nun, dass das onunload-Ereignis des iframes manuell aufgerufen wird, indem die src-Eigenschaft geändert wird, anstatt dass es ausgelöst wird, wenn die windowEl.destroy-Methode den iframe aus dem DOM entfernt. (hat die Idee von here).

Wenn Sie diesen Code verwenden möchten, löschen Sie einfach die vorhandene Funktion closingJobs und kopieren Sie diesen Code an seiner Stelle einfügen. Es sollte sowohl mit 0.9.7 und 0.9.8 MochaUI arbeiten, und entweder Mootools 1.2.4 oder 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

auch, welche Version von mootools verwendet wird. mootools 1.3 hat element.prototype.destroy etwas vereinfacht, so sieht es so aus: http://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L677 vs die alte http://github.com/mootools/mootools-core/blob/1.2x/Source/Element/Element.js#L579, das zu der seltsamen 'clean()' Funktion oben geht. –

+0

1.2.4. Ich sehe das gleiche passiert mit 1.3 (mit der 0.9.7 MochaUI Build, das ist). In meinem Test habe ich die Kompatibilitätsebene verwendet, obwohl ich nicht sicher bin, ob das ein Faktor ist. Die Fehlerbehebung, die ich oben vorgeschlagen habe, hat dieselbe Auswirkung auf das Speicherverhalten von Chrome mit 1.3 wie mit 1.2.4. All das könnte sich jedoch ändern: Aufgrund deines ersten Kommentars habe ich in Mocha's Github etwas mehr herumgestochert - ich wusste gar nicht, dass der Zweig 0.9.8 so viel Aktivität in letzter Zeit hatte! Danke, dass Sie mich darauf aufmerksam gemacht haben. – freenatec

+0

keine Sorgen! Das alte Mochaui war ... schwer zu bearbeiten. Ich unterstütze immer noch meinen eigenen Zweig aufgrund der großen Anzahl von Fixes, die ich implementieren musste und jetzt wird die Verwendung von 0.9.8 oder 1.0 fast unmöglich sein! Naja! –