2010-10-31 25 views
26

Contexte: Je travaille actuellement sur un site intranet qui utilise la bibliothèque MochaUI (travail du virtual desktop demo). J'utilise Mootools 1.2.4 et MochaUI 0.9.7. Les fenêtres qui sont ouvertes dans mon implémentation de "bureau virtuel" chargent leur contenu via les iframes. Certaines des pages chargées sont assez lourdes en termes de css et de script, il est donc important que les objets Window soient correctement collectés lorsque l'utilisateur ferme une fenêtre. Ceci est ostensiblement pris en charge par la bibliothèque (il fait un bon travail lors de l'utilisation de Firefox).Chrome ne parvient pas à libérer de la mémoire, la collecte des ordures ne se produit pas comme prévu (bibliothèque Mootools/MochaUI)

Mise à jour La question initialement affichée était devenue trop longue à cause des modifications/mises à jour ultérieures. Le titre n'était plus précis, alors j'ai changé ça aussi. Aussi, voir ma réponse ci-dessous pour une solution partielle.

Voici les points essentiels:

  1. Chrome comme autant fout:

    • Chrome ne parvient pas à libérer la mémoire allouée pour les objets de fenêtre MochaUI quand ils sont fermés. Au lieu de cela, l'utilisation de la mémoire de Chrome se fige (littéralement) au niveau atteint après que la fenêtre ait fini de charger son contenu iframe, définissant une limite inférieure sur l'utilisation de la mémoire jusqu'à ce que la page soit actualisée.
    • La mémoire utilisée par le processus continue d'augmenter avec les ouvertures/fermetures de fenêtres suivantes. Finalement, un certain type de plafond est atteint, et l'utilisation de la mémoire arrête de grimper aussi fortement/commence à osciller au lieu de sauter de façon spectaculaire.
    • Ce problème est plus apparent lorsque les fenêtres en question chargent un contenu iframe assez lourd (en termes de mémoire). La fenêtre que j'utilise pour tous les tests charge une page de 580 kb (non mise en cache) dans son iframe.
  2. Étrangement, la collecte des ordures prévu -t lieu, quand

    • le navigateur est ensuite réduite au minimum
    • un autre onglet est ouvert dans la même fenêtre du navigateur
    • une Mémoire Timeline est en cours d'enregistrement dans Developer Tools. (option comédie)
    • Ce comportement suggère-t-il des approches possibles pour résoudre # 1?
+5

question très intéressante et une bonne explication. Je ne sais pas exactement quel est le coupable, même si je vous préviens qu'il y a une chance qu'il n'y ait pas de solution. Ou s'il y en a un, pas facile. Google adopte une approche très fainéante de la programmation. Bien que Chrome semble charger le plus rapidement et utiliser moins de mémoire de tous les principaux navigateurs, il est criblé de bugs dont je ne rêverais pas dans Firefox ou Opera. Pareil avec Android vs iOS. – stevendesu

+0

J'ai posté une version très détaillée/longue de cette question sur le forum d'aide Google Chrome pour les webmasters et je n'ai pas reçu de réponse, alors cette fois-ci j'ai décidé de la rendre plus précise! Je suis d'accord que cela semble être un bug (ou une bizarrerie de la façon dont Chrome détermine quels objets doivent être collectés). C'est comme s'il y avait un niveau plus élevé de ramasse-miettes qui se produit lorsque Chrome est réduit, et mes objets de fenêtre ne sont pas complètement vides par les normes de Chrome, peut-être. Merci pour le commentaire! – freenatec

+4

@steven_desu: Google adopte non seulement une approche paresseuse à l'égard de la programmation, mais elle semble également apathique à l'égard de tout type de plaintes ou de problèmes que ses utilisateurs pourraient commettre. –

Répondre

6

Je ne sais pas si cela a été testé sous Windows, mais si donc gardez à l'esprit que chaque fois que vous réduisez au minimum une fenêtre dans les fenêtres, il déplace toutes les données du fichier d'échange. Lors de l'ouverture de la fenêtre, les blocs de mémoire ne seront plus déplacés à moins que le programme ne tente d'y accéder, de sorte que les déchets resteront dans le fichier d'échange mais ne seront pas collectés.

Si vous l'automatisiez, cela ne ralentirait pas seulement le programme mais ne vous aiderait pas non plus avec des problèmes de mémoire.

voir l'adresse suivante pour un peu plus d'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

Toutes les machines sur l'intranet qui utiliseront le site fonctionneront sous Windows XP, je crois. Je n'avais pas considéré ce problème avec le fichier d'échange, même si l'automatisation/le piratage de Chrome à son état Minimized (en quelque sorte, quel que soit l'effet) était un concept long-shot ...Idéalement, je trouverais un moyen de changer mon code javascript pour que Chrome reconnaisse les objets à ramasser comme d'habitude. – freenatec

+1

Avez-vous essayé de définir les variables/objets à zéro une fois que vous avez terminé avec eux? – William

+0

Dans la mesure où je saisis les fonctions de la bibliothèque qui gèrent le comportement de fermeture de fenêtre, il semble que tous les objets pertinents soient mis à zéro lorsqu'une fenêtre se ferme. Le contenu chargé dans les fenêtres (dans les iframes) est plus mon propre code, et il est un peu brouillon et contribue probablement à des fuites ... cependant, je dois noter que Firefox libère clairement de la mémoire lorsque les fenêtres se ferment (3-5) MB sur environ 5 secondes). D'autre part, l'utilisation de la mémoire du processus Chrome approprié reste statique lorsque les fenêtres sont fermées, et la seule chose qui le fait diminuer est la minimisation du navigateur. – freenatec

3

Mise à jour
Les modifications suivantes à la fonction MochaUI closingJobs sont une grande amélioration sur ce que je tition ici. La principale modification est maintenant que l'onuload de l'iframe est appelé manuellement en modifiant la propriété src, au lieu d'être déclenché lorsque la méthode windowEl.destroy supprime l'iframe du DOM. (J'ai eu l'idée de here).

Si vous souhaitez utiliser ce code, supprimez simplement la fonction closingJobs existante et copiez ce code à sa place. Il devrait travailler à la fois avec MochaUI 0.9.7 et 0.9.8, et Mootools 1.2.4 ou 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

aussi, quelle version de mootools est utilisée. mootools 1.3 a quelque peu simplifié element.prototype.destroy donc il ressemble à ceci: http://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L677 vs l'ancien http://github.com/mootools/mootools-core/blob/1.2x/Source/Element/Element.js#L579 qui va à la fonction bizarre 'clean()' ci-dessus. –

+0

1.2.4. Je vois les mêmes choses se produire avec 1.3 (avec la construction MochaUI 0.9.7, c'est). Dans mon test, j'ai utilisé la couche de compatibilité, même si je ne sais pas si c'est un facteur ici. Le correctif que je suggère ci-dessus a le même effet sur le comportement de la mémoire de Chrome avec 1.3 qu'avec 1.2.4. Tout cela pourrait changer, cependant: d'après votre premier commentaire, je me suis baladé un peu plus dans le github de moka ui - je ne savais pas que la branche 0.9.8 avait tellement d'activité récente! Merci d'avoir porté cela à mon attention. – freenatec

+0

pas de soucis! le vieux mochaui a été ... difficile de travailler avec. Je suis toujours en charge de ma propre branche en raison du grand nombre de correctifs que j'ai dû mettre en œuvre et maintenant utiliser 0.9.8 ou 1.0 sera presque impossible! tant pis! –