This project is archived and is in readonly mode.

#312 ✓duplicate
BONZaI

fx.slide memory Leak in IE6 - documentation bug

Reported by BONZaI | August 11th, 2008 @ 09:22 PM

Hi everyone, First, It is my first ticket, and I would like to thank every contributor of mootools, and I would like to thank especially the programming team at the origin of mootools !

I am in charge of developping a web interface that will be exclusively used with IE6, which forces me to be quite concerned about memory leaking (life is hard sometimes).

In order to offer a fancy "suggest" to my customers, I decided to use fx.slide effects with dynamically created divs.

However, after a whole afternoon of intensive efforts, I unfortunately did not manage to fix a simple memory leak with IE6. I tried to remove every event I could (with "removeEvents", without any paramater), dispose, empty and destroy every element I handled, avoided closures and anonymous functions, removed every memory reference to any objet/element etc. But none of these precautions allowed me to avoid a bloody IE memory-leak.

I even tried a very simple example applying the fx.slide to the form input only (witouh any dynamically created divs)


this.resultSlideFx = new fx.Slide(inputElement,{/*optins*/};
this.resultSlideFx.removeEvents();
this.resultSlideFx.wrapper.removeEvents();
this.resultSlideFx.wrapper.destroy();
this.resultSlideFx.wrapper.dispose(); //should be useless, but I'm desperate !
this.resultSlideFx.wrapper = null;
this.resultSlideFx = null;
//and I apply same kind of stuff to inputElement, which is my form element ...

... And this simple piece of code provokes IE6 mem-leaking.

I don't know if I misunderstood something, but I'm getting quite lost.

By the way, the online doc concerning the fx.slide constructor seems to be incorrect. Indeed, it says that if I provide : var myFx = new Fx.Slide(element[, options]); with an option attribute "wrapper", myFx would use this wrapper instead of dyamically create a new one. But it seems (if I'm not wrong) that you have to store a container-element in element with the name "wrapper" if you want the fx.Slide to use it as a slide-wrapper.

I precise that I'm using Firebug (it helped me to detect the fx.Slide wrapper element), and Drip 0.5 to inspect the IE. DOM memory leaks (and this program seems to say that the responsible of the leak is a surviving reference to the slide-wrapper element. I didn't succeed to remove this last element reference).

Did I missed something, or is this a bug, or is it just definitely hopeless to think that you can build serious web applications with IE6 ?

Thank in advance !

Comments and changes to this ticket

  • Daniel Steigerwald

    Daniel Steigerwald August 11th, 2008 @ 09:58 PM

    I share your desperation with you. I'm working on big app, and I suffer from big IE6/7 leaks too. Some of them comes from MooTools, another from bad coding style, but leaking hydra should be killed forever! :-)

    It's seems Moo team is overloaded (last half year) from another work, and I understand it, Mootools is open source, many thanks for it existen, and I like mooforum mantra: "We are not here to complain about these things. We are here to do something about."

    I have my own version of mootools, with many fixes, also leaks (but not all yet). Currently I'm finishing my big project, absolutely no spare time, but I promise, I will make my own fork on GIT, hope in one months. If you could wait, do it :)

    And some notes: * drip of course (but drip has bugs too) * better is process explorer (to see how many memory is really consumed) * temporally fix: http://www.hedgerwow.com/360/dht... * only reliable pattern: comment all, f5 f5 f5 f5.., see process explorer, uncomment something, f5 f5 f5 f5.. see process explorer.. etc.

  • BONZaI

    BONZaI August 11th, 2008 @ 10:10 PM

    I totally agree with what you said, Daniel. From the thanks to the contribution notes, I would not say it in a better way. By the way, I forgot to precise that processExplorer is my "very best friend" in the memory-leak hunting. And actually, I already had programmed a few 500 lines of code, and realizing that I had serious memory problems (using f5 f5 f5 ... with processExplorer memory consumption chart), I finally commented everything, and identified the fx.slide as the responsible for this naughty problem (I had taken every measure I could to avoid these leakings).

    Thanks for your comments and your notes !

  • Daniel Steigerwald

    Daniel Steigerwald August 11th, 2008 @ 10:40 PM

    I would like to collect all moo leaks (also from old moo forum /online again, thanx boys/), and fix them all. Next step is to get all nifty fixes from JQuery (almost done :)

    If I had no occupation :-), I would definitely implement these features:

    • rewrite mootools to be prototypeless and namespaced optionally (some guy do it here too)
    • adjust moo classes to allow javascript codding style less tiresome (this, bind, ":" everywhere, I hate it :), major part of my class members are private, so not have to be prototyped, some old not so good example: http://daniel.steigerwald.cz/hum...
  • BONZaI

    BONZaI August 12th, 2008 @ 02:50 PM

    Hello guys,

    I have just fixed the memory leak I've reported. The fault was mine (in some sense), and here is the way I processes to fix the trouble : I was using some class "LeakLicker" I had created to clean memory on leaving the page (with the event unload). This class stores objects in a hash, and has a method called cleanEverythingUp, wich calls removeEvents, destroy and removes by hand every function attribute on every stored element :

    
    /**
     * Classe qui s'appuye sur un Hash, dont l'instance est destinés à recevoir toutes les variables crées dans le code,
     * et à être invoquée lors du onUnload pour invoquer destroy sur tous les éléments qu'elle contient, et TOUT déférencer
     * (tout du moins ce qui est dans le Hash de l'instance)
     *
     * Cette classe est créée uniquement pour nettoyer les vieilles traces de Internet Explorer après son passages et ses
     * fuites douteuses. ELLE EST INDISPENSABLE POUR EVITER DE SURCHARGER IE6 ET QU'IL NE DEVIENNE, APRES QUELQUES CLICKS DE
     * NAVIGATION, QU'UNE LARVE AMORPHE ET BOULIMIQUE
     */
    var LeakLicker = new Class({
    	initialize: function (){
    		this.collector = new Hash();
    	},
    
    	set : function(key, object){
    		this.collector.set(key, object);
    	},
    	get : function(key, object){
    		return (this.collector.get(key));
    	},
    
    	 /**
    	  * Applique destroy sur chaque objet du collector, pour chaque élément vide toutes les fonctions ,
    	  * et s'auto-détruit (l'instance manipulée n'est alors plus qu'un objet vide)
    	  *
    	  */
    	 cleanEverythingUp :  function(verboseAlert){
    		var verboseAlert = $pick(verboseAlert, false);	//on prend la valeur par défaut false sur verboseAlert
    	 	var verboseString = "LeakLicker - cleanEverythingUp : ";
    	 	//fonction de suppression d'un élément
    		var cleanUpObjectFunction = function(objectToCleanUp, key){
    			if (verboseAlert) {
    				verboseString += "\n- element  : " + key + " - " + objectToCleanUp;
    			}
    			//si l'objet n'est pas undefined, on suppr. ses events, on le destroy, on le vide : on supprime ttes ses fonctions(IMPORTANT !)
    			if ($defined(objectToCleanUp)) {
    				//invoque removeEvents sur l'objet si contient cette méthode
    				if ($defined(objectToCleanUp.removeEvents) && $type(objectToCleanUp.removeEvents) == "function") {
    					objectToCleanUp.removeEvents();
    					if (verboseAlert) {
    						verboseString += " - removeEvents invoked";
    					}
    				}
    				//invoque "destroy" sur l'objet si contient cette méthode (NB : destroy invoque lui même empty() et dispose() )
    				if ($defined(objectToCleanUp.destroy) && $type(objectToCleanUp.destroy) == "function") {
    					objectToCleanUp.destroy();
    					if (verboseAlert) {
    						verboseString += " - destroyed invoked";
    					}
    				}//supprime toutes les fonctions restantes de l'objet "à la main" (un peu violent tout de même, MAIS NECESSAIRE POUR IE et ses fuites)
    					for (property in objectToCleanUp) {
    						//alert("property to remove by hand : "+property+" - "+objectToCleanUp[property]);
    						if (objectToCleanUp[property] && $type(objectToCleanUp[property]) == "function"){
    							objectToCleanUp[property] = $empty();//fonction vide
    						}
    					}
    					if (verboseAlert && $defined(property)) {
    						verboseString += " - element properties removed by hand";
    					}
    			}
    			objectToCleanUp = null;
    
    		}//fin de la fonction de suppression d'un élément
    
    		//*** destroys tous les éléments du hash ***
    		this.collector.each(cleanUpObjectFunction);
    		cleanUpObjectFunction 	= null;
    
    
    		if (verboseAlert){verboseString += "\n\n ... Ready to self-destruct ";	}
    		//self destruction !!
    		this.collector.empty();
    		this.collector			= null;
    		this.cleanEverythingUp	= $empty();
    		this.selfDestroy 		= $empty();
    		this.initialize			= $empty();
    		this.set				= $empty();
    		if (verboseAlert){verboseString += "\n - self-destruct accomplished";	alert(verboseString);}
    		verboseAlert 	= null;
    		verboseString 	= null;
    	 },
    
    	 /**
    	 * Alias de cleanEverythingUp, parce que le nom peut être un peu plus parlant pour certains
    	 */
    	selfDestroy : this.cleanEverythingUp
    
    });
    

    (sorry, it's in English and French - I'm working with non English-speakers - and my English isn't that good!).

    In every class I create, I use a "LeakLicker", and I store every Element I use in the class within the leakLicker. The fact is that I had made a mistake in my leakLicker definition, and the function attributes were not removed from the stored elements, which provoked a memory leak in IE6. Now, it's fixed and there is no trouble anymore.

    However, I would like to add a few remarks : - the documentation bug about fx.slide and the options attribute "wrapper" is still valid. Thus, if you don't store a "wrapper" element in the slided element on fx.slide, you won't be able to "have a hand" on the fx.slide wrapper element (unless you grab the wrapper yourself with myFxSlide.wrapper). - Using fx.slide, If this wrapper element is not cleaned (as the leakLicker does), memory leaks appear in IE6.

    Thanks again to Daniel Steigerwald , and to every mootoolser for making this project exist !

  • Daniel Steigerwald

    Daniel Steigerwald August 15th, 2008 @ 01:13 PM

    Look at #319 You could adjust mootools.js, or make new file moofix.js(must be placed after mootools.js!).

  • Aaron Newton

    Aaron Newton February 19th, 2009 @ 12:23 AM

    • Assigned user changed from “Valerio” to “Aaron Newton”
    • Tag changed from 1.2, docs, fx.slide, ie, leak to docs, fx.slide, ie, leak
    • Milestone cleared.
  • fakedarren

    fakedarren February 8th, 2010 @ 03:52 PM

    • State changed from “new” to “open”
  • Christoph Pojer

    Christoph Pojer September 3rd, 2010 @ 01:36 PM

    • State changed from “open” to “duplicate”
    • Milestone order changed from “0” to “0”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Shared Ticket Bins

Pages