PRODUKTE| ORGANISATION| WIEDERVERKAUF| ENTWICKLUNG| KONTAKT  
 
   
 
 
PRODUKTE
 Content Management
 Intranet/Extranet
 Framework
 
ORGANISATION
 Referenzen
 Kunden
 Case Studys
 
WIEDERVERKAUF
 Überblick
 Noch heute Starten
 
ENTWICKLUNG
 Screenshots
 1. Memory Leak in IE 6/7
 2. Links
 3. DOM - JS Engine
 4. Example Table
 5. Closures
 6. DOM insertion
 7. innerHTML !!!
 8. DWR / ajaxCFC
 
KONTAKT
 Kontaktformular


Example Table

With this example I will show some aspects of memory leak problems

Example: We create a table and want to store additional data for each cell, not the cell data itself as part of <td>.....</td>. You might be able to expand the DOM cell by expando variables, but this is very slow and does not perform well, beside the leak problem.

Correct way: Keep JS part and DOM part clear devided. Our example: we create a div and load a table into it. Lets say, the div exists already on you HTML page with id = "myDiv".

var MyDiv= document.getElementById('MyDiv');

// Create an Array to hold the extended cell data

var arrTable= new array();

We create the table with 2 rows an 3 cells per row. And we add an expando (Event Handler to ech cell). To prevent closure (see next part) I do NOT write the ID as identifier into the function like onclick=showCellData("cell_"+i+"_"+y). I just use onclick= showCellData(), therfore I do not have to care about closure var i and y.

function createTable() {

var MyTable = document.createElement("TABLE");
for(var i=0;i<2;i++){

var arrTable[i] = new Array();
var MyTR = document.createElement("TR");
for(var y=0;y<3;i++){

var MyTD = document.createElement("TD");
MyTD.id ="cell_"+ i +"_"+y;
MyTD.onclick=showCellData(); 
//MyTD.onclick=showCellData(="cell_"+ i +"_"+y);  // 1) might cause a closure leak
arrTable[i][y]="Some extended Data for each cell";
 // MyTD.MyCustomCellData = "Some extended Data for each cell"; // 2) Circular Ref.
MyTR.appendChild(MyTD);
MyTD=null;

}
MyTable.appendChild(MyTR);
MyTR=null;

}
MyDiv.appendChild(MyTable);  // Add the table to the div:
 MyTable=null;
MyDiv = null;

}

Now we need to know which cell has been clicked, using showCellData();

function showCellData(event) {

if(window.attachEvent){

var MyCellId = event.srcElement.id;  // IE solution

}else{

var MyCellId = e.target.id;   // FF solution

}
 // var MyCellId = this.id should work as well
 // Now we split the id into the row- and cell-id to access the JS engine Array

var arrSplit= MyCellId.split("_"):
var trId= arrSplit[1];
var tdId= arrSplit[2];

// now we access the additional data of the cell, stored in the array
var MyData = arrTable[trId][ tdId];
alert(MyCellData);  // do whatever you want with the extendend cell data

OR

document.getElementById(MyCellId).style.background="red;
MyCellId=null;

}
 

In the example above:

- We assing null to each temporary JS variable like MyTD = null
- We don't use expando Variable like: MyTD.MyCustomCellData
- We assing an expando event Handler to the td without any parameters for the function showCellData();
- We assign an id to MyTD variable. MyTD.id =.... This does NOT LEAK because it is a standard DOM property

There is no need to set EVERY variable to null (for example i and y), but it is not wrong, as it gives the memory back immediately, otherwhise the garbage collecter does the job (if no Leak condition exists)

In this example we created a "reference" from the TD's of DOM to "TD's" in the array arrTable. There is no real reference between the DOM and the JS engine. Therfore no LEAK will occur. The only bridge ist the value of the cell's id. Therfore we can access eighter the JS Array or the DOM element by the string, representing the id.
[ "cell_"+ i +"_"+y ]. For example to set all TD's to background blue, you just loop the table's array and assign the styles by document.getElementById( "cell_"+ i +"_"+y).style.background="red";

So what is missing? The example may still leak....

On unload of the page, we have to remove ALL expando Event handlers, that we assigned to the TD.

Create a function cleanup() that loops the Table Array and remove all event handlers on unload of the page, or at the time when you destroy the table dynamically. I only show the part of removing the event handler. I assume that it is clear, that you get the i and y for each cell by looping the array. Then you are able to create the cell id [ "cell_"+ i +"_"+y ].

document.getElementById(MyCellId).onclick=null;

OR

var myCell = document.getElementById(MyCellId);
myCell.onclick=null;
myCell=null;

If you use an array to store real references to DOM elements you may run into troubles. It is not wrong to do this, but having complex code you may run into closure coditions and to find the reason for a LEAK becomes difficult. Therfore I recoment to keep JS part and DOM part cleanly separated (especially for not very experianced programmers)

Examples simplyfied of REAL DOM - JS references:

var arrayDom = new array();...

arrayDom[0][0] = document.createElement("TABLE");
arrayDom[1][0] = document.createElement("TR");
arrayDom[0][0].appendChild(arrayDom[1][0]);
arrayDom[1][1] = document.createElement("TR");
arrayDom[0][0].appendChild(arrayDom[1][1]);

OR

Div1 = document.createElement("DIV");
DIV1.id="div_1";
DIV1.onmousedown=new function(){......}
arrayDivs[1] = Div1;

If you clean up such an examples above correctly, there is no leak conditon.

Eg.

arrayDivs[1].onmousedown = null;  // no Leak (if the function does not use lokal variables - see closures)
arrayDivs[1]=null;

 

 

     
     
KONTAKT
 
Adresse
    posOS GmbH
Thundorferstrasse 31
8500 FrauenfelD
     
 
Kontakt
    phone: +41(0)794145464
Email: info@posos.net
Anfragen: angebot@posos.net