Memory Leak under Internet Explorer

159 views
Skip to first unread message

Luca Masini

unread,
Nov 15, 2007, 7:35:20 AM11/15/07
to Google Web Toolkit
Hi guys, I have some problems in an Intranet application that use many
forms during all the day !!!
After some time the memory footprint of IE become very very large
(some hundreds MB !!!) and the application start to be really
slow !!!!
After some investigation, I noticed that the problem is due to the
fact that we use a prototype pattern for our panel, so I did a test
case that show the issue:

package it.esselunga.testgwt.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class TestFormGWT implements EntryPoint {

private int createCounter = 0;

private SimplePanel container = null;

Timer timer = new Timer(){

public void run() {

if(remove){
if(container !=null){
container.removeFromParent();
if( !singleton.isChecked() ){
container = null;
}
}

remove = false;
}
else{
if(container==null || !singleton.isChecked()){
createCounter++;
container = new SimplePanel();
DOM.setElementProperty(container.getElement(), "id",
"container");
FormPanel formPanel = new FormPanel();
TextBox textBox = new TextBox();
textBox.setText("Created: " + createCounter );
formPanel.add(textBox);
container.add(formPanel);
}

RootPanel.get("slot4").add(container);

remove = true;
}
}

};

private final CheckBox singleton = new CheckBox("singleton");

private boolean remove = false;

public void onModuleLoad() {
Button startButton = new Button("Start Adding Form");
startButton.addClickListener(new ClickListener(){
public void onClick(Widget sender) {
timer.scheduleRepeating(100);
}
});

Button stopButton = new Button("Stop Adding Form");
stopButton.addClickListener(new ClickListener(){
public void onClick(Widget sender) {
timer.cancel();
}
});

RootPanel.get("slot1").add(startButton);
RootPanel.get("slot1").add(stopButton);
RootPanel.get("slot3").add(singleton);



}
}

After short time your IE will explode !!!

Investigating in sIEve I saw that the GWT UI framework correctly
detach callback, JavaScript object and the parent DOM container object
from the document. But the nodes last there !!
They are not garbaged.
Is there any issue in the way I code ? Is this normal under Internet
Explorer ?

Milan Jaric

unread,
Nov 15, 2007, 7:52:25 AM11/15/07
to Google-We...@googlegroups.com
your timer has no delay
 
you missing
// Schedule the timer to run once in 5 seconds.
    t.schedule(5000);


 

Luca Masini

unread,
Nov 15, 2007, 3:00:44 PM11/15/07
to Google Web Toolkit
Milan the delay on t.schedule(5000) must be set if I want to schedule
something to be executed once in the future, instead I want a
repeating running timer, for that I used scheduleRepeating.

But that is not related to the memory leak problem !!!!


On 15 Nov, 13:52, "Milan Jaric" <milan.ja...@gmail.com> wrote:
> your timer has no delayhttp://google-web-toolkit.googlecode.com/svn/javadoc/1.4/com/google/g...
>
> you missing
>
> // Schedule the timer to run once in 5 seconds.
> t.schedule(5000);
>
> --
> Milan Jaric

George Georgovassilis

unread,
Nov 15, 2007, 6:19:13 PM11/15/07
to Google Web Toolkit
Good catch Luca

I run your test on IE7 and it exposes indeed a memory leak. I tried a
few variations:

I placed the timer function into a loop in order to generate garbage
faster - I can verify that the working set memory grows continiously,
starts swapping and makes the entire OS unusable, not just your
application.

At first I suspected it must have to do something with RootPanel, but
if you replace the references to slots with a single FlowPanel, the
effect is equally evident.
Just for fun then I wrote a variation which simple adds and then
removes "container" to the root panel. Again memory consumption rises
continuously, although at a much slower pace.

Luca Masini

unread,
Nov 16, 2007, 5:31:45 PM11/16/07
to Google Web Toolkit
I think it's simething related to GWT !!!
I did and example in pure JavaScript and it doesn't leak a bit of
memory:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">

<title>Test Case</title>

<script type="text/javascript"><!--
var counter = 0;

function listener(event) {
alert(event);
}

function discardElement(element) {
var garbageBin = document.getElementById('IELeakGarbageBin');
if (!garbageBin) {
garbageBin = document.createElement('DIV');
garbageBin.id = 'IELeakGarbageBin';
garbageBin.style.display = 'none';
document.body.appendChild(garbageBin);
}

// move the element to the garbage bin
garbageBin.appendChild(element);
garbageBin.innerHTML = '';
element.__listener = null;
}

function createSimpleForm(){
var container = document.getElementById('container');

if( document.getElementById('containing-div') ){
var div = document.getElementById('containing-div');

discardElement(div);
}

var div = document.createElement('div');
div.id = 'containing-div';
div.__listener = listener;

var form = document.createElement('form');
form.width = '175px';
form.__listener = listener;

var input = document.createElement('input');
input.type= 'text';
input.value = ++counter;
input.width = 175;
input.__listener = listener;

var save = document.createElement('input');
save.type= 'button';
save.value = 'Save';
save.__listener = listener;

var cancel = document.createElement('input');
cancel.type= 'button';
cancel.value = 'Cancel';
cancel.__listener = listener;

container.appendChild(div);
div.appendChild(form);
form.appendChild(input);
form.appendChild(save);
form.appendChild(cancel);
}

var intervalID;

function launch(){
intervalID =
setInterval("createSimpleForm();",document.getElementById('timeout').value);
}

function stop(){
if( intervalID ){
clearInterval(intervalID);
}
}

--></script>
</head>
<body>
<input type="button" value="Launch Test Case"
onclick="javascript:launch();"/>
<br/>
<input type="button" value="Stop Test Case"
onclick="javascript:stop();"/>
<br/>
<label>Timeout</label><input id="timeout" type="text" value="100" />
<br/>
<div style="width:300px;">
<div id="container">

</div>
</div>
</body>
</html>

So again Google experts, where is the problem ? In the way I use
GWT ???? There is a secret way of using GWT not to leak memory ?


On 16 Nov, 00:19, George Georgovassilis <g.georgovassi...@gmail.com>
wrote:

Milan Jaric

unread,
Nov 16, 2007, 8:49:27 PM11/16/07
to Google-We...@googlegroups.com
Have any of you try to recursively remove widgets? first textbox then simple panel. here is why

if we have something similar to this :
Lets say that someDiv is first an only child of body tag.

var someDiv = document.getElementById('someDiv'); // or var someDiv = document.firstChild;
var jsComponent = document.createElement('div');
// now nesting
someDiv.appendCild (someDiv);

and later

body.removeChild(someDiv); // we have removed child from body but grand child is not removed from hierarchy it has left in memory. if you do this n-times more, then you will get big memory leak. maybe FF2 have fixed this but i think microsoft has only fixed in IE7 CSS issues, not JavaScript.

Gwt uses appendChild and removeChild js functions to remove widgets from hierarchy, witch is natural way. Maybe my opinion is wrong, but try to make recursive call  of widget child removal, to see what is happening.

Milan

Milan Jaric

unread,
Nov 16, 2007, 9:11:06 PM11/16/07
to Google-We...@googlegroups.com
 garbageBin.innerHTML = ''; is not same as garbageBin.removeChild(childElement);
when you call innerHTML = something or nothing,  garbageBins childs or none is interpreted   again (all of them even garbageBin it self ) it is not same process!

GWT uses removeChild. Code below is from gwt.js

// called from removeFromParent
function removeChild(parent, child){
  $clinit_6();
  $removeChild(impl, parent, child);
}
...
function $removeChild(this$static, parent, child){
  parent.removeChild(child); // <-- native function
}

setInterval("createSimpleForm();",document.getElementById ('timeout').value);



--
Milan Jaric

WongTseng

unread,
Nov 16, 2007, 11:20:36 PM11/16/07
to Google-We...@googlegroups.com
can you elaborate on the difference between innerHTML="" and
removeChild. which way is better?

2007/11/17, Milan Jaric <milan...@gmail.com>:


--
Wong Tseng
王曾

Luca Masini

unread,
Nov 17, 2007, 5:47:24 PM11/17/07
to Google Web Toolkit
Guys, may be I was not clear enough.
The JavaScript code I posted is MEMORY SAFE, I mean that the memory
footprint is rock steady and doesn't move from where it start !!!
It's the GWT example (that does the same thing) that leak a lot of
memory.
And I think It's due to some strange IE's GC behaviour.

When I do the $elementToRemoveParent.innertHTML = '' to avoid the
pseudo-leak problem, a strange effect in IE that is not a problem for
old-style application (where the page is refreshed everytime), but
it's a killer for AJAX style application.
Also the ordere of insertion is important in IE, because if you create
a tree and then you attach it to the document's DOM, you leak a script
context, if does the contrary no problem.

Also Milan, as you can see from the Pure JavaScript example, removing
the tree root-node is enough !!! You don't need to recursively remove
all the nodes !!!

I feel a smell about this memory problem........

If it comes from me, then I'm using a code style that it's the real
cause of the leak.......

If it comes from somewhere else, then no one has yet done a production
application using GWT, an application that works all the day !!!

Please, can someone tell me that I'm doing wrong, really I do prefere
this smell source !!!

Bye.

Luca Masini

unread,
Nov 17, 2007, 5:48:14 PM11/17/07
to Google Web Toolkit
I'm not a JavaScript expert, but they have the same visual effect and
also innerHTML = '' doesn't leak memory, instead removeChild does !!!!

What do you think it's better ?

On 17 Nov, 05:20, WongTseng <wangzengveryc...@gmail.com> wrote:
> can you elaborate on the difference between innerHTML="" and
> removeChild. which way is better?
>
> 2007/11/17, Milan Jaric <milan.ja...@gmail.com>:
>
> > garbageBin.innerHTML = ''; is not same as garbageBin.removeChild
> > (childElement);
> > when you call innerHTML = something or nothing, garbageBins childs or none
> > is interpreted again (all of them even garbageBin it self ) it is not same
> > process!
>
> > GWT uses removeChild. Code below is from gwt.js
>
> > // called from removeFromParent
> > function removeChild(parent, child){
> > $clinit_6();
> > $removeChild(impl, parent, child);
> > }
> > ...
> > function $removeChild(this$static, parent, child){
> > parent.removeChild(child); // <-- native function
> > }
>
> > On Nov 16, 2007 11:31 PM, Luca Masini <luca.mas...@gmail.com> wrote:
>
> > > I think it's simething related to GWT !!!
> > > I did and example in pure JavaScript and it doesn'tleaka bit of
> > > > I run your test on IE7 and it exposes indeed amemoryleak. I tried a
> > > > few variations:
>
> > > > I placed the timer function into a loop in order to generate garbage
> > > > faster - I can verify that the working setmemorygrows continiously,
> > > > starts swapping and makes the entire OS unusable, not just your
> > > > application.
>
> > > > At first I suspected it must have to do something with RootPanel, but
> > > > if you replace the references to slots with a single FlowPanel, the
> > > > effect is equally evident.
> > > > Just for fun then I wrote a variation which simple adds and then
> > > > removes "container" to the root panel. Againmemoryconsumption rises
> > > > continuously, although at a much slower pace.
>
> > > > On Nov 15, 1:35 pm, Luca Masini <luca.mas...@gmail.com> wrote:
>
> > > > > Hi guys, I have some problems in an Intranet application that use many
> > > > > forms during all the day !!!
> > > > > After some time thememoryfootprint of IE become very very large
> ...
>
> leggi tutto

Reinier Zwitserloot

unread,
Nov 17, 2007, 8:22:33 PM11/17/07
to Google Web Toolkit
Ordinarily, any discussion on whether innerHTML is better than
removeChild is ridiculous. Who cares? In almost all cases, innerHTML
is faster than futzing about with the DOM, if it -really- matters.
However, if one version leaks memory and the other doesn't, even if
it's clearly a browser bug, let me just answer the obvious for you:

In that case, innerHTML is better. Duh!
> > > > > > Button startButton = new Button("Start Adding Form");...
>
> read more >>

Milan Jaric

unread,
Nov 18, 2007, 6:33:21 PM11/18/07
to Google-We...@googlegroups.com
Even inerrHTML does not removes them from memory.
Last time I haven't give you full answer of problem you have.

problem is with REFERENCES in javascript , and problem sounds like this.

WHEN EVER YOU MAKE A REFERENCE TO AN OBJECT, THEN MAKE ANOTHER, AND THEN TRY TO DISPOSE OBJECT FROM MEMORY BY MAKEING REFERENCE2 = NULL; YOU DIDN'T REMOVE OBJECT FROM MEMORY, YOU HAVE REMOVE REFERENCE TO THAT OBJECT. WHEN ALL REFERENCES ARE REMOVED FROM OBJECT THEN AND ONLY THEN JAVASCRIPT GC WILL REMOVE OBJECT FROM MEMORY

my point is, when GWT loads widget it makes reference to that object and then puts it in some dom element. The first is variable
 TextBox textBox = new TextBox();  and second is RootPanel.get("slot1").add(textBox); when you remove textBox from slot1 like this :

 textBox.getParent().remove(textBox);  you didn't remove textBox from memory just from slot1 ( javascript : slot1.removeChild(textBox); )
so textBox still have reference to it self and only way to destroy that object is textBox = null;
I hope it is now clearer :) if not here is example below, just paste it in new html document between <body> and </body>
------------
<div id="container" style="border:1px solid #000;">

</div>

<div id="log">
</div>
<SCRIPT type="text/javascript">

    var anChildHolder = document.createElement("span");
   
    var referenceToInnerElement = document.createElement("b");
    referenceToInnerElement.id = "someId";
    referenceToInnerElement.innerHTML = "I am a child of span element";

    anChildHolder.appendChild(referenceToInnerElement);


    container = document.getElementById("container");

    alert("Now, reference problem, nesting an child, first lets see what are our references");
    //alert("[anChildHolder] = " + anChildHolder + "\n[referenceToInnerElement] = " + referenceToInnerElement );
    container.appendChild(anChildHolder);
    alert("Lets see what references are: \n[anChildHolder] = " + anChildHolder + "\n[ anChildHolder.childNode[0]] = " + anChildHolder.childNodes[0]);
    alert("now we remove anChildHolder to see if referenceToInnerElement whas removed to");
    container.removeChild(anChildHolder); // same as container.removeChild(anChildHolder);
    alert("Lets see what references are: \n[anChildHolder] = " + anChildHolder + "\n[anChildHolder.childNode[0]] = " + anChildHolder.childNodes[0]);
    alert("succesfuly removed child but ;) what is that memory leak!!! it seams to me grand child has left in memory, what a hell is going on!!!");   
    alert("Lets see what references are: \n[anChildHolder] = " + anChildHolder + "\n[referenceToInnerElement] = " + referenceToInnerElement + "\nOk remove them");   
   

anotherReference1 = anChildHolder
     
    anChildHolder = null;
    referenceToInnerElement = null;
   
///////////
    alert("Lets see what references are now : \nanChildHolder = " + anChildHolder + "\nreferenceToInnerElement = " + referenceToInnerElement + "\nOh Thank God! They are gone");   
    alert("Lets see what references are: \n[anotherReference1] = " + anotherReference1 + "\n[anotherReference1.childNode[0]] = " + anotherReference1.childNodes[0] + "\nOk remove them");
anotherReference1  = null;
alert("Lets see what references are: \n[anotherReference1] = " + anotherReference1 + "\n[anotherReference1.childNode[0]] = " + anotherReference1.childNodes[0] + "\nTHE END");
</SCRIPT>
-------------------------

George Georgovassilis

unread,
Nov 19, 2007, 3:08:53 AM11/19/07
to Google-We...@googlegroups.com
One of GWT's widget handling advantages would be the abstraction of such details into the implementation so that the widget user does not have to worry about them any more.

Luca Masini

unread,
Nov 19, 2007, 4:30:16 AM11/19/07
to Google Web Toolkit
GWT claim (and I think DOES) that he can transparently handle such
things.
When I add a Widget to a panel and then I remove it the onAttach and
onDetach events handle all the internals !!!
So the circular reference IS NOT THE PROBLEM !!!!
Nulling references is important when you want the JavaScript side to
be disposed, or you will have a reference from ROOT and mark and sweep
GC will not start !!!

The problem is somewhere else, but I don't know where it is.....

I'm starting to think that it's impossibile to use Internet Explorer
for serious AJAX application !!!

On 19 Nov, 00:33, "Milan Jaric" <milan.ja...@gmail.com> wrote:
> Even inerrHTML does not removes them from memory.
> Last time I haven't give you full answer of problem you have.
>
> problem is with REFERENCES in javascript , and problem sounds like this.
>
> WHEN EVER YOU MAKE A REFERENCE TO AN OBJECT, THEN MAKE ANOTHER, AND THEN TRY
> TO DISPOSE OBJECT FROM MEMORY BY MAKEING REFERENCE2 = NULL; YOU DIDN'T
> REMOVE OBJECT FROM MEMORY, YOU HAVE REMOVE REFERENCE TO THAT OBJECT. *WHEN
> ALL REFERENCES ARE REMOVED FROM OBJECT THEN AND ONLY THEN JAVASCRIPT GC WILL
> REMOVE OBJECT FROM MEMORY*
>
> my point is, when GWT loads widget it makes reference to that object and
> then puts it in some dom element. The first is variable
> *TextBox textBox = new TextBox(); *and second is
> *RootPanel.get("slot1").add(textBox);
> *when you remove textBox from slot1 like this :
> *textBox.getParent().remove(textBox); *you didn't remove textBox from
> memory just from slot1 ( javascript : slot1.removeChild(textBox); )
> so textBox still have reference to it self and only way to destroy that
> object is *textBox = null;*
> ...
>
> leggi tutto

giovanni...@gmail.com

unread,
Nov 19, 2007, 5:12:56 AM11/19/07
to Google Web Toolkit
"I'm starting to think that it's impossibile to use Internet Explorer
for serious AJAX application !!! "

QFT!

Hi Luca,
We are currently developing a really big (maybe too big... Oo)
application in GWT.
We have noticed the IE memory prob a couple of weeks ago... Since that
we are praying
to Padre Pio hoping for the miracle BEFORE 31/12: our final release
date!

crossing fingers
Giovanni
> ...
>
> read more >>

dflorey

unread,
Nov 19, 2007, 5:22:23 AM11/19/07
to Google Web Toolkit
Hi,
I've written a large call-center app using gwt and guess what...
After working with the app for a longer time (< 1h) IE is about 600mb
and gets very slow. Everything runs fine in Firefox.
So something is obviously wrong here.
I thought it was related to rpc calls in IE but now I'm confused and
think it's more a general problem related to dynamic dom and it's just
triggered by my rpc calls.
???

Daniel

On 19 Nov., 11:12, "giovanni.ganas...@gmail.com"
> ...
>
> Erfahren Sie mehr >>- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -

Luca Masini

unread,
Nov 20, 2007, 12:29:25 PM11/20/07
to Google Web Toolkit
Which widget libraries are you using ?
Flat GWT widgets ? Or gwt-ext, or mygwt or whatever ?
> ...
>
> leggi tutto

Milan Jaric

unread,
Nov 20, 2007, 1:51:00 PM11/20/07
to Google-We...@googlegroups.com
dflorey, it is hard to guess what is problem from your input, but consider this, in JavaScript, like in Java, there is no destructor and if you want to remove an object then you must remove all references to that object, so Garbage collector can remove it.

There is also one issue with  IE6 and with ActiveX version of xml http request object, I have found it in post here on google groups http://groups.google.com/group/comp.lang.javascript/msg/556048483801bd96


Milan



> > >  *textBox.getParent ().remove(textBox);  *you didn't remove textBox from

> > > memory just from slot1 ( javascript : slot1.removeChild(textBox); )
> > > so textBox still have reference to it self and only way to destroy that
> > > object is *textBox = null;*
> > > I hope it is now clearer :) if not here is example below, just paste it in
> > > new html document between <body> and </body>
> > > ------------
> > > <div id="container" style="border:1px solid #000;">
>
> > > </div>
>
> > > <div id="log">
> > > </div>
> > > <SCRIPT type="text/javascript">
>
> > >     var anChildHolder = document.createElement("span");
>
> > >     var referenceToInnerElement = document.createElement ("b");



--
Milan Jaric

dflorey

unread,
Nov 21, 2007, 7:37:33 AM11/21/07
to Google Web Toolkit
Hi,
I'm using gwt-dragdrop and gwt-chimes (beside the pure gwt widgets).
I'll try to narrow down the problem once I find the time to provide a
snippet to reproduce the leak.
It's quite hard to track down the problem, once the app has become
huge :-(
Thanks anyway for all your input!

Cheers,
Daniel

On 20 Nov., 18:29, Luca Masini <luca.mas...@gmail.com> wrote:
> Which widget libraries are you using ?
> Flat GWT widgets ? Or gwt-ext, or mygwt or whatever ?
>
> On 19 Nov, 11:22, dflorey <daniel.flo...@gmail.com> wrote:
>
>
>
> > Hi,
> > I've written a large call-center app using gwt and guess what...
> > After working with the app for a longer time (< 1h) IE is about 600mb
> > and gets very slow. Everything runs fine in Firefox.
> > So something is obviously wrong here.
> > I thought it was related to rpc calls in IE but now I'm confused and
> > think it's more a general problem related to dynamic dom and it's just
> > triggered by my rpc calls.
> > ???
>
> > Daniel
>
> > On 19 Nov., 11:12, "giovanni.ganas...@gmail.com"
>
> > <giovanni.ganas...@gmail.com> wrote:
> > > "I'm starting to think that it's impossibile to use Internet Explorer
> > > for serious AJAX application !!! "
>
> > > QFT!
>
> > > Hi Luca,
> > > We are currently developing a really big (maybe too big... Oo)
> > > application in GWT.
> > > We have noticed the IEmemoryprob a couple of weeks ago... Since that
> > > we are praying
> > > to Padre Pio hoping for the miracle BEFORE 31/12: our final release
> > > date!
>
> > > crossing fingers
> > > Giovanni
>
> > > On Nov 19, 10:30 am, Luca Masini <luca.mas...@gmail.com> wrote:
>
> > > > GWT claim (and I think DOES) that he can transparently handle such
> > > > things.
> > > > When I add a Widget to a panel and then I remove it the onAttach and
> > > > onDetach events handle all the internals !!!
> > > > So the circular reference IS NOT THE PROBLEM !!!!
> > > > Nulling references is important when you want the JavaScript side to
> > > > be disposed, or you will have a reference from ROOT and mark and sweep
> > > > GC will not start !!!
>
> > > > The problem is somewhere else, but I don't know where it is.....
>
> > > > I'm starting to think that it's impossibile to use Internet Explorer
> > > > for serious AJAX application !!!
>
> > > > On 19 Nov, 00:33, "Milan Jaric" <milan.ja...@gmail.com> wrote:
>
> > > > > Even inerrHTML does not removes them frommemory.
> > > > > Last time I haven't give you full answer of problem you have.
>
> > > > > problem is with REFERENCES in javascript , and problem sounds like this.
>
> > > > > WHEN EVER YOU MAKE A REFERENCE TO AN OBJECT, THEN MAKE ANOTHER, AND THEN TRY
> > > > > TO DISPOSE OBJECT FROMMEMORYBY MAKEING REFERENCE2 = NULL; YOU DIDN'T
> > > > > REMOVE OBJECT FROMMEMORY, YOU HAVE REMOVE REFERENCE TO THAT OBJECT. *WHEN
> > > > > ALL REFERENCES ARE REMOVED FROM OBJECT THEN AND ONLY THEN JAVASCRIPT GC WILL
> > > > > REMOVE OBJECT FROMMEMORY*
>
> > > > > my point is, when GWT loads widget it makes reference to that object and
> > > > > then puts it in some dom element. The first is variable
> > > > > *TextBox textBox = new TextBox(); *and second is
> > > > > *RootPanel.get("slot1").add(textBox);
> > > > > *when you remove textBox from slot1 like this :
> > > > > *textBox.getParent().remove(textBox); *you didn't remove textBox from
> > > > >memoryjust from slot1 ( javascript : slot1.removeChild(textBox); )
> > > > > alert("succesfuly removed child but ;) what is thatmemoryleak!!! it
> > > > > seams to me grand child has left inmemory, what a hell is going on!!!");
>
> > > > > alert("Lets see what references are: \n[anChildHolder] = " +
> > > > > anChildHolder + "\n[referenceToInnerElement] = " + referenceToInnerElement +
> > > > > "\nOk remove them");
>
> > > > > anotherReference1 = anChildHolder
>
> > > > > anChildHolder = null;
> > > > > referenceToInnerElement = null;
>
> > > > > ///////////
> > > > > alert("Lets see what references are now : \nanChildHolder = " +
> > > > > anChildHolder + "\nreferenceToInnerElement = " + referenceToInnerElement +
> > > > > "\nOh Thank God! They are gone");
> > > > > alert("Lets see what references are: \n[anotherReference1] = " +
> > > > > anotherReference1 + "\n[anotherReference1.childNode[0]] = " +
> > > > > anotherReference1.childNodes[0] + "\nOk remove them");
> > > > > anotherReference1 = null;
> > > > > alert("Lets see what references are: \n[anotherReference1] = " +
> > > > > anotherReference1 + "\n[anotherReference1.childNode[0]] = " +
> > > > > anotherReference1.childNodes[0] + "\nTHE END");
> > > > > </SCRIPT>
> > > > > -------------------------
>
> > > > > On Nov 18, 2007 2:22 AM, Reinier Zwitserloot <reini...@gmail.com> wrote:
>
> > > > > > Ordinarily, any discussion on whether innerHTML is better than
> > > > > > removeChild is ridiculous. Who cares? In almost all cases, innerHTML
> > > > > > is faster than futzing about with the DOM, if it -really- matters.
> > > > > > However, if one version leaksmemoryand the other doesn't, even if
> > > > > > it's clearly a browser bug, let me just answer the obvious for you:
>
> > > > > > In that case, innerHTML is better. Duh!
>
> > > > > > On Nov 17, 11:48 pm, Luca Masini <luca.mas...@gmail.com> wrote:
> > > > > > > I'm not a JavaScript expert, but they have the same visual effect and
> > > > > > > also innerHTML = '' doesn'tleakmemory, instead removeChild does !!!!

dflorey

unread,
Nov 21, 2007, 7:41:59 AM11/21/07
to Google Web Toolkit
My problem is: Everything runs fine in Firefox, so the problem is in
gwt not in my app. I don't think I have to take care of internal
references as gwt is all about browser abstraction.
Or am I missing something?

On 20 Nov., 19:51, "Milan Jaric" <milan.ja...@gmail.com> wrote:
> dflorey, it is hard to guess what is problem from your input, but consider
> this, in JavaScript, like in Java, there is no destructor and if you want to
> remove an object then you must remove all references to that object, so
> Garbage collector can remove it.
>
> There is also one issue with IE6 and with ActiveX version of xml http
> request object, I have found it in post here on google groupshttp://groups.google.com/group/comp.lang.javascript/msg/556048483801bd96
>
> Milan
> > > > > *textBox.getParent().remove(textBox); *you didn't remove textBox
> > from
> > > > > memory just from slot1 ( javascript : slot1.removeChild(textBox); )
> > > > > so textBox still have reference to it self and only way to destroy
> > that
> > > > > object is *textBox = null;*
> > > > > I hope it is now clearer :) if not here is example below, just paste
> > it in
> > > > > new html document between <body> and </body>
> > > > > ------------
> > > > > <div id="container" style="border:1px solid #000;">
>
> > > > > </div>
>
> > > > > <div id="log">
> > > > > </div>
> > > > > <SCRIPT type="text/javascript">
>
> > > > > var anChildHolder = document.createElement("span");
>
> > > > > var referenceToInnerElement = document.createElement("b");

Reinier Zwitserloot

unread,
Nov 21, 2007, 8:02:01 AM11/21/07
to Google Web Toolkit
Yes; you're not being very specific about where the memory leak is.
How do you expect us to debug this properly? Debugging memory leakage
is just very difficult. However, begin with eliminating third party
libraries. If y ou don't use gwt-dnd and gwt-chimes, what happends
then?
> > > > > > > > > > > function discardElement(element) {...
>
> read more >>

George Georgovassilis

unread,
Nov 21, 2007, 8:10:30 AM11/21/07
to Google-We...@googlegroups.com
Apart from that the problem was already narrowed down (see our previous posts in this thread) to detaching groups of widgets - we even provided a simple yet verifiable test case in a single class. I was under the impression that IE can handle cyclic graphs as long as no events are associated with widgets - and GWT would handle that part with its centralised event system.

Milan Jaric

unread,
Nov 21, 2007, 10:14:16 AM11/21/07
to Google-We...@googlegroups.com
I have found one problem which can cause  memory leak in javascript.
First, anonymous event handlers ( i will wrote js only not GWT code )

This is wrong :
window.onload=function(){
    // obj will be gc'ed as soon as
    // it goes out of scope therefore no leak.
    var obj = document.getElementById("element");
   
    // this creates a closure over "element"
    // and will leak if not handled properly.
    obj.onclick=function(evt){
        ... logic ... it is the same way as gwt anonymously handling events ( so this is wrong )
    };
};

Now to handle it properly we must do this
window.onload=function (){
    // obj will be gc'ed as soon as
    // it goes out of scope therefore no leak.
    var obj = document.getElementById("element");
    obj.onclick=element_click;
};

//HTML DOM object "element" refers to this function
//externally. We have avoided circular reference here!!!! So memory leak is gone
function element_click(evt){
    ... logic ...
}

This pattern will not leak because as soon as the function window.onload finishes execution, the JS object obj will be marked for garbage collection. So there won't be any reference to the DOM node on the JS side.

Conclusion is that we must avoid anonymous event handling as more as possible. I will try to discover more issues.

Regards, Milan
--
Milan Jaric

Luca Masini

unread,
Nov 21, 2007, 1:06:41 PM11/21/07
to Google Web Toolkit
Well, you say that GWT should take care of this, but is nearly
impossible.
Also thinking at the various leakege that has IE with many patterns
make this really difficult to Google's guys.
But my test case is very FLAT, few lines of code and not much more, so
I think that should be at near-zero memory footprint.
How can we think to develop memory savy applications if also the
fundamentals are not themsef memory savy ?
> ...
>
> leggi tutto

dflorey

unread,
Nov 22, 2007, 4:54:49 AM11/22/07
to Google Web Toolkit
I'll try to remove the 3rd party libs to see if this makes any
difference.
@Rainer: I'm still confused: If my application runs fine on Firefox
(without memory leakage) it should run fine on IE as well or am I
wrong? If the memory leak is still there after removing 3rd party libs
I would consider this a gwt bug. Agreed?


On 21 Nov., 19:06, Luca Masini <luca.mas...@gmail.com> wrote:
> Well, you say that GWT should take care of this, but is nearly
> impossible.
> Also thinking at the various leakege that has IE with many patterns
> make this really difficult to Google's guys.
> But my test case is very FLAT, few lines of code and not much more, so
> I think that should be at near-zero memory footprint.
> How can we think to develop memory savy applications if also the
> fundamentals are not themsef memory savy ?
>
> On 21 Nov, 13:41,dflorey<daniel.flo...@gmail.com> wrote:
>
>
>
> > My problem is: Everything runs fine in Firefox, so the problem is in
> > gwt not in my app. I don't think I have to take care of internal
> > references as gwt is all about browser abstraction.
> > Or am I missing something?
>
> > On 20 Nov., 19:51, "Milan Jaric" <milan.ja...@gmail.com> wrote:
>
> > >dflorey, it is hard to guess what is problem from your input, but consider
> > > this, in JavaScript, like in Java, there is no destructor and if you want to
> > > remove an object then you must remove all references to that object, so
> > > Garbage collector can remove it.
>
> > > There is also one issue with IE6 and with ActiveX version of xml http
> > > request object, I have found it in post here on google groupshttp://groups.google.com/group/comp.lang.javascript/msg/556048483801bd96
>
> > > Milan
>

George Georgovassilis

unread,
Nov 22, 2007, 5:01:42 AM11/22/07
to Google-We...@googlegroups.com
Well, you say that GWT should take care of this, but is nearly
impossible.

Just because we didn't bother to trace it down to the root doesn't necessary mean that GWT can't be bothered :-)
One thing I didn't check (though it is on my todo list!) is whether leaks are still evident once I disassemble the widgets. Now we remove an entire panel + children from the root and we get a leak. Does it happen when we remove each child sepperately before removing the parent?

Reinier Zwitserloot

unread,
Nov 22, 2007, 8:05:53 AM11/22/07
to Google Web Toolkit
You're basically wrong. That kind of utopian thinking has no place in
fragmented browser world. It's fundamentally wrong, for two reasons:

1) Because GWT lets you do anything via DOM.* and JSNI, you can easily
set up some perfectly acceptable code that our local idiot cousin, IE,
can't handle without leaking. In code which uses strictly GWT widgets,
that should be hard to impossible, though, and

2) Because it is certainly possible to write code that leaks in
general, but, due to a 'bug' on firefox, actually doesn't leak so much
there. For example because you've stuffed some faulty code in an IE
only block.
> > > > > ) it...
>
> read more >>

stuckagain

unread,
Nov 23, 2007, 3:13:19 AM11/23/07
to Google Web Toolkit
Hey,

A similar problem exists with IFrames, I started a discussion and
filed a bug report for that issue.
The cause seems to be the same:
When IE does removeChild, the child is removed from the DOM tree, but
it is not cleared.
The trick is to set the src to javascript:'' which forces the hosted
page to unload. After that I use outerHTML to really clear the
element.

For a bit more reading on this subject see:
http://code.google.com/p/google-web-toolkit/issues/detail?id=1821

Although I reported this problem, the Google engineer or contributor
that looked at the bug simply change the state to NotPlanned, while it
is clear that he did not understand that I was actually giving him the
solution. There is also a discusion in the GWT contributor group about
this. Maybe we should join forces in pointing out that this is a major
showstopped for big applications.

This is the thread by the way
http://groups.google.com/group/Google-Web-Toolkit-Contributors/browse_thread/thread/fc0fe19dea871f36/b19f4184050d0f83#b19f4184050d0f83


David

On Nov 22, 10:54 am, dflorey <daniel.flo...@gmail.com> wrote:
> I'll try to remove the 3rd party libs to see if this makes any
> difference.
> @Rainer: I'm still confused: If my application runs fine on Firefox
> (withoutmemoryleakage) it should run fine on IE as well or am I
> wrong? If thememoryleak is still there after removing 3rd party libs
> I would consider this a gwt bug. Agreed?
>
> On 21 Nov., 19:06, Luca Masini <luca.mas...@gmail.com> wrote:
>
>
>
> > Well, you say that GWT should take care of this, but is nearly
> > impossible.
> > Also thinking at the various leakege that has IE with many patterns
> > make this really difficult to Google's guys.
> > But my test case is very FLAT, few lines of code and not much more, so
> > I think that should be at near-zeromemoryfootprint.
> > How can we think to developmemorysavy applications if also the
> > fundamentals are not themsefmemorysavy ?
> > > > > > We have noticed the IEmemoryprob a couple of weeks ago... Since that
> > > > > > we are praying
> > > > > > to Padre Pio hoping for the miracle BEFORE 31/12: our final release
> > > > > > date!
>
> > > > > > crossing fingers
> > > > > > Giovanni
>
> > > > > > On Nov 19, 10:30 am, Luca Masini <luca.mas...@gmail.com> wrote:
>
> > > > > > > GWT claim (and I think DOES) that he can transparently handle such
> > > > > > > things.
> > > > > > > When I add a Widget to a panel and then I remove it the onAttach and
> > > > > > > onDetach events handle all the internals !!!
> > > > > > > So the circular reference IS NOT THE PROBLEM !!!!
> > > > > > > Nulling references is important when you want the JavaScript side to
> > > > > > > be disposed, or you will have a reference from ROOT and mark and sweep
> > > > > > > GC will not start !!!
>
> > > > > > > The problem is somewhere else, but I don't know where it is.....
>
> > > > > > > I'm starting to think that it's impossibile to use Internet Explorer
> > > > > > > for serious AJAX application !!!
>
> > > > > > > On 19 Nov, 00:33, "Milan Jaric" <milan.ja...@gmail.com> wrote:
>
> > > > > > > > Even inerrHTML does not removes them frommemory.
> > > > > > > > Last time I haven't give you full answer of problem you have.
>
> > > > > > > > problem is with REFERENCES in javascript , and problem sounds like
> > > > > this.
>
> > > > > > > > WHEN EVER YOU MAKE A REFERENCE TO AN OBJECT, THEN MAKE ANOTHER, AND
> > > > > THEN TRY
> > > > > > > > TO DISPOSE OBJECT FROMMEMORYBY MAKEING REFERENCE2 = NULL; YOU
> > > > > DIDN'T
> > > > > > > > REMOVE OBJECT FROMMEMORY, YOU HAVE REMOVE REFERENCE TO THAT OBJECT.
> > > > > *WHEN
> > > > > > > > ALL REFERENCES ARE REMOVED FROM OBJECT THEN AND ONLY THEN JAVASCRIPT
> > > > > GC WILL
> > > > > > > > REMOVE OBJECT FROMMEMORY*
>
> > > > > > > > my point is, when GWT loads widget it makes reference to that object
> > > > > and
> > > > > > > > then puts it in some dom element. The first is variable
> > > > > > > > *TextBox textBox = new TextBox(); *and second is
> > > > > > > > *RootPanel.get("slot1").add(textBox);
> > > > > > > > *when you remove textBox from slot1 like this :
> > > > > > > > *textBox.getParent().remove(textBox); *you didn't remove textBox
> > > > > from
> > > > > > > >memoryjust from slot1 ( javascript : slot1.removeChild(textBox); )
> > > > > > > > seams to me grand child has left inmemory, what a hell is going
> > > > > > > > > However, if one version leaksmemoryand the other doesn't, even
> > > > > if
> > > > > > > > > it's clearly a browser bug, let me just answer the obvious for
> > > > > you:
>
> > > > > > > > > In that case, innerHTML is better. Duh!
>
> > > > > > > > > On Nov 17, 11:48 pm, Luca Masini <luca.mas...@gmail.com> wrote:
> > > > > > > > > > I'm not a JavaScript expert, but they have the same visual
> > > > > effect and
> > > > > > > > > > also innerHTML = '' doesn't leakmemory, instead removeChild
> > > > > does !!!!
>
> > > > > > > > > > What do you think it's better ?
>
> > > > > > > > > > On 17 Nov, 05:20, WongTseng <wangzengveryc...@gmail.com> wrote:
>
> > > > > > > > > > > can you elaborate on the difference between innerHTML="" and
> > > > > > > > > > > removeChild. which way is better?
>
> > > > > > > > > > > 2007/11/17, Milan Jaric <milan.ja...@gmail.com>:
>
> > > > > > > > > > > > garbageBin.innerHTML = ''; is not same as
> > > > > garbageBin.removeChild
> > > > > > > > > > > > (childElement);
> > > > > > > > > > > > when you call innerHTML = something or nothing, garbageBins
> > > > > childs
> > > > > > > > > or none
> > > > > > > > > > > > is interpreted again (all of them even garbageBin it self
> > > > > ) it
>
> ...
>
> read more >>- Hide quoted text -
>
> - Show quoted text -

iblu...@gmail.com

unread,
Nov 28, 2007, 4:43:46 AM11/28/07
to Google Web Toolkit
Guys,
Even gmail (new version) which is claimed to be developed with GWT has
a memory leak with IE7 and non with FF
I am currently evaluating GWT to develop a large application, sadly,
the memory leak are IE problem
please advise if any one knows how to resolve this matter

Cheers,

Reinier Zwitserloot

unread,
Nov 28, 2007, 6:21:19 PM11/28/07
to Google Web Toolkit


On Nov 28, 10:43 am, "iblust...@gmail.com" <iblust...@gmail.com>
wrote:
> Guys,
> Even gmail (new version) which is claimed to be developed with GWT has
> a memory leak with IE7 and non with FF
> I am currently evaluating GWT to develop a large application, sadly,
> the memory leak are IE problem
> please advise if any one knows how to resolve this matter
>

gmail predates GWT. it is therefore obviously not written with it. GWT
is inspired by it, and has nicked a number of tactics used by gmail.

mP

unread,
Nov 29, 2007, 3:39:44 AM11/29/07
to Google Web Toolkit

You cant use innerHtml because by doing that you are removing the
child dom elements from the dom but you are not notifying the widgets
themselves that they have been removed. This means references are not
broken to parent panels etc resulting in a memory leak.
On Nov 17, 3:20 pm, WongTseng <wangzengveryc...@gmail.com> wrote:
> can you elaborate on the difference between innerHTML="" and
> removeChild. which way is better?
>
> 2007/11/17, Milan Jaric <milan.ja...@gmail.com>:
> ...
>
> read more >>

Milan Jaric

unread,
Nov 29, 2007, 3:48:19 AM11/29/07
to Google-We...@googlegroups.com
It is true, If we have cyclic references form JavaScript world to DOM world (and back) and if we are trying to find workaround by removing object by simply braking Dom hierarchy in DOM world and leaving references as is in javascript world, than we have memory leak, because Dom GC and JS GC are two separated GC's!

> > >                        var save = document.createElement ('input');
> > > container.getElement (), "id",

George Georgovassilis

unread,
Nov 29, 2007, 3:44:49 AM11/29/07
to Google-We...@googlegroups.com


You cant use innerHtml because by doing that you are removing the
child dom elements from the dom but you are not notifying the widgets
themselves that they have been removed. This means references are not
broken to parent panels etc resulting in a memory leak.


.... but DOM.removeChild doesn't notify the widgets either
Reply all
Reply to author
Forward
0 new messages