Nog niet eerder uitgebreid behandeld, maar wel een topic op zich waard. Microsoft Internet Explorer (en in mindere mate Mozilla) heeft last van memory leaks in Javascript, die voorkomen bij gebruik van DOM, en ActiveX.
De gemiddelde gebruiker weet dit niet, developers die dagelijks aan website gerelateerde projecten werken en veelvuldig gebruik maken van Javascript wel.
Het verwijderen van elementen met childs, zonder het eerst verwijderen van de childs resulteerd bijvoorbeeld in het aanwezig blijven van deze childs in het geheugen. Resultaat is dat al deze childs eerst moeten worden opgeruimd, alvorens het element op te ruimen.
Voor het gemiddelde image swap script is dit niet echt een probleem. De geheugenlekken zullen niet al te bijzonder zijn.
Het wordt wel een probleem, zodra je, zoals tegenwoordig mogelijk, gebruik gaat maken van de voordelen van Javascript op een grotere basis. Navigatie structuren via XML, complete UI componenten etc. Je gaat dan al snel geheugenlekken tegenkomen.
Met dit topic hoop ik dat er wat meer duidelijkheid komt over het herkennen, opsporen, en voorkomen van deze lekken.
De oorzaak van het lekker in MSIE is de manier van garbage collection in MSIE. Javascript gebruik “mark and sweep” welke immuun is voor circular references. De MSIE is alleen immuun voor circular references die verwijzen naar pure JS objecten. (geen ActiveX of DOM objects).
http://msdn.microsoft.com...es/02/04/web/default.aspx
Geheugenlekken:
Als je de DOM form, en element objects gaat extenden met je eigen methods. Properties toevoegen, zelfs als ze groot zijn, veroorzaakt geen geheugenlekken.
Zodra je XML/XSLT of XSD gaat gebruiken, wordt je geheugenlek 2x tot 3x zo groot als normaal.
Javascripts embedded in je pagina, met document.write() calls lekken. Deze zijn op te lossen door deze te vervangen met document.createElement en document.createTextNode()
DOM objects aanmaken, en hier event handlers aanhangen. De event handlers lekker. Een oplossing hiervoor schijnt het setten van een null value op onunload te zijn.
In plaats van dit:
mijnObject.elementReference = document.getElementById("someReference") ;
Doe dit:
mijnObject.elementReference = "someReference";
function something(obj) {
var elm = document.getElementById(obj.elementReference) ;
}
Voor het verwijderen van referenties:
Voor:
var o = {};
var el = document.getElementById(sId);
o.element = el;
el.jsObject = o;
Kan je zoiets gebruiken:
o.element.jsObject = null;
o.element = null;
Spui je tips, ervaringen
Er is op het internet niet bijzonder veel te vinden over dit onderwerp, en het bestaat meestal uit wat losse flodders.
De gemiddelde gebruiker weet dit niet, developers die dagelijks aan website gerelateerde projecten werken en veelvuldig gebruik maken van Javascript wel.
Het verwijderen van elementen met childs, zonder het eerst verwijderen van de childs resulteerd bijvoorbeeld in het aanwezig blijven van deze childs in het geheugen. Resultaat is dat al deze childs eerst moeten worden opgeruimd, alvorens het element op te ruimen.
Voor het gemiddelde image swap script is dit niet echt een probleem. De geheugenlekken zullen niet al te bijzonder zijn.
Het wordt wel een probleem, zodra je, zoals tegenwoordig mogelijk, gebruik gaat maken van de voordelen van Javascript op een grotere basis. Navigatie structuren via XML, complete UI componenten etc. Je gaat dan al snel geheugenlekken tegenkomen.
Met dit topic hoop ik dat er wat meer duidelijkheid komt over het herkennen, opsporen, en voorkomen van deze lekken.
De oorzaak van het lekker in MSIE is de manier van garbage collection in MSIE. Javascript gebruik “mark and sweep” welke immuun is voor circular references. De MSIE is alleen immuun voor circular references die verwijzen naar pure JS objecten. (geen ActiveX of DOM objects).
http://msdn.microsoft.com...es/02/04/web/default.aspx
Het resultaat is dus dat je alle referenties handmatig moet verbreken tussen JS objects en DOM/ActiveX objects.Q Why doesn't the garbage collector release a reference to an ActiveX® object when the page is refreshed? I know JScript utilizes lazy garbage collection, but in this case memory allocated is never released when you refresh the page. Futhermore, when you refresh the page, memory comsumption grows because of the new ActiveX object that's created."
"A The problem is that it's Internet Explorer that holds the reference to the function which in turn holds a reference to the ActiveX object that isn't being released.
For performance reasons, Internet Explorer does not kill the DOM nodes until either you navigate to a different page or you close the browser. Refreshing the current page will not kill the nodes. The problem is not that the garbage collector is lazy—the problem is that it's not immune to circular reference chains which contain objects not created by the JScript engine. The browser object model is created by the browser, not by the language engine."
Geheugenlekken:
Als je de DOM form, en element objects gaat extenden met je eigen methods. Properties toevoegen, zelfs als ze groot zijn, veroorzaakt geen geheugenlekken.
Zodra je XML/XSLT of XSD gaat gebruiken, wordt je geheugenlek 2x tot 3x zo groot als normaal.
Javascripts embedded in je pagina, met document.write() calls lekken. Deze zijn op te lossen door deze te vervangen met document.createElement en document.createTextNode()
DOM objects aanmaken, en hier event handlers aanhangen. De event handlers lekker. Een oplossing hiervoor schijnt het setten van een null value op onunload te zijn.
In plaats van dit:
mijnObject.elementReference = document.getElementById("someReference") ;
Doe dit:
mijnObject.elementReference = "someReference";
function something(obj) {
var elm = document.getElementById(obj.elementReference) ;
}
Voor het verwijderen van referenties:
Voor:
var o = {};
var el = document.getElementById(sId);
o.element = el;
el.jsObject = o;
Kan je zoiets gebruiken:
o.element.jsObject = null;
o.element = null;
Spui je tips, ervaringen