Hi!
we are experiencing that the browser (IE6, IE7 and Firefox) uses more and more memory in our application. We are using input forms a lot and traced back the problem to the usage of the ComboBox widget.
I wrote a little demo for the problem that interactively allows to
- add 50 Html widgets to a container
- add 50 Comboboxes to a container
- remove all widgets from the container
I tried to follow the memory consumption in window's taskmanager when doing the following actions:
1. add 50 Html Widgets (multiple times if you want)
2. clear
3. note the memory size of iexplorer (the first clear results in less memory than on startup of the application, no idea why)
4. add 50 html widgets (multiple times if you want)
5. clear
6. the memory is about the same as in step 3
7. add 50 comboboxes
8. clear
9. the memory did not go down on clearing the comboboxes and shows the same result as after step 7
I tried to do the same with IESieve, but there neither memory nor dom objects go down ever. So I am not sure if there is a problem with IESieve or my code :-)
The code to test:
Code:
package testmemoryleak.client;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.layout.TableLayout;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class ComboboxMemoryleak implements EntryPoint {
public static final int WIDGET_COUNT = 50;
LayoutContainer container;
public void onModuleLoad() {
Viewport viewport = new Viewport();
viewport.setEnableScroll(true);
LayoutContainer buttonContainer = new LayoutContainer();
container = new LayoutContainer();
Button clearButton = new Button("clear", new SelectionListener<ComponentEvent>() {
public void componentSelected(ComponentEvent ce) {
container.removeAll();
container.layout();
}
});
buttonContainer.add(clearButton);
Button addBadButton = new Button("add widgets with memory leak", new SelectionListener<ComponentEvent>() {
public void componentSelected(ComponentEvent ce) {
long start = System.currentTimeMillis();
for (int index = 0; index < WIDGET_COUNT; ++index) {
container.add(createWidgetMemLeak(index));
}
container.layout();
}
});
buttonContainer.add(addBadButton);
Button addGoodButton = new Button("add 'good' widgets", new SelectionListener<ComponentEvent>() {
public void componentSelected(ComponentEvent ce) {
for (int index = 0; index < WIDGET_COUNT; ++index) {
container.add(createWidgetNormal(index));
}
container.layout();
}
});
buttonContainer.add(addGoodButton);
container.setScrollMode(Scroll.AUTO);
container.setLayout(new TableLayout(5));
viewport.add(buttonContainer);
viewport.add(container);
RootPanel.get().add(viewport);
}
/**
* Creates and returns a widget without memory leak.
*/
public Widget createWidgetNormal(int index) {
return new Html("widget " + index);
}
/**
* Creates and returns a widget that has a memory leak (memory in browser will not be freed
* after removal of this widget).
*/
public Widget createWidgetMemLeak(int index) {
ComboBox<BaseModel> box = new ComboBox<BaseModel>();
box.setId("id" + index);
box.setEditable(false);
ListStore<BaseModel> store = new ListStore<BaseModel>();
for (int modelIndex = 0 ; modelIndex < 7; ++modelIndex) {
BaseModel data = new BaseModel();
data.set("id", modelIndex);
data.set("index", modelIndex);
data.set("label", "key" + modelIndex);
data.set("value", "value" + modelIndex);
store.add(data);
}
box.setStore(store);
box.setDisplayField("label");
return box;
}
}
Versions used (server on linux, browser on windows)
Browser: IE6, IE7, Firefox 3 on windows XP
GXT: 1.0.1 and 1.0.2
GWT: 1.5-RC1 (linux)