PDA

View Full Version : Internet Explorer 8 Memory Leak when removing items from the ListStore backing a Grid



forseta
17 Nov 2011, 5:38 PM
Hi All,

Using the sencha example of a Grid and creating a timer to remove all elements from the Grid and re-add them shows a gradual increase in memory consumed in Internet Explorer 8 (Firefox and Chrome do not exhibit this issue).

Memory utilization for Internet Explorer according to task manager of a dedicated test machine went from approximately 80mb to 700mb over 4 days.

The code below is verbose as I have tried to make as minimal changes to the provided example as possible




public class GridLoadTestDisplay extends LayoutContainer
{

private static List<Stock> stocks;

public GridLoadTestDisplay()
{
stocks = new ArrayList<Stock>();
for (int i=0;i<1000;i++)
{
stocks.add(new Stock(""+i));
}
}

private class GridExample extends LayoutContainer
{

private ColumnModel cm;
private Grid<Stock> grid;

@Override
protected void onRender(Element parent, int index)
{
super.onRender(parent, index);
setLayout(new FlowLayout(10));
getAriaSupport().setPresentation(true);

final NumberFormat currency = NumberFormat.getCurrencyFormat();
final NumberFormat number = NumberFormat.getFormat("0.00");
final NumberCellRenderer<Grid<Stock>> numberRenderer = new NumberCellRenderer<Grid<Stock>>(currency);

GridCellRenderer<Stock> change = new GridCellRenderer<Stock>()
{
public String render(Stock model, String property, ColumnData config, int rowIndex, int colIndex,
ListStore<Stock> store, Grid<Stock> grid)
{
double val = (Double)model.get(property);
String style = val < 0 ? "red" : GXT.isHighContrastMode ? "#00ff5a" : "green";
String v = number.format(val);

return "<span qtitle='" + cm.getColumnById(property).getHeader() + "' qtip='" + v
+ "' style='font-weight: bold;color:" + style + "'>" + v + "</span>";
}
};

GridCellRenderer<Stock> gridNumber = new GridCellRenderer<Stock>()
{
public String render(Stock model, String property, ColumnData config, int rowIndex, int colIndex,
ListStore<Stock> store, Grid<Stock> grid)
{
return numberRenderer.render(null, property, model.get(property));
}
};

List<ColumnConfig> configs = new ArrayList<ColumnConfig>();

ColumnConfig column = new ColumnConfig();
column.setId("name");
column.setHeader("Company");
column.setWidth(200);
column.setRowHeader(true);
configs.add(column);

column = new ColumnConfig();
column.setId("symbol");
column.setHeader("Symbol");
column.setWidth(100);
configs.add(column);

column = new ColumnConfig();
column.setId("last");
column.setHeader("Last");
column.setAlignment(HorizontalAlignment.RIGHT);
column.setWidth(75);
column.setRenderer(gridNumber);
configs.add(column);

column = new ColumnConfig("change", "Change", 100);
column.setAlignment(HorizontalAlignment.RIGHT);
column.setRenderer(change);
configs.add(column);

column = new ColumnConfig("date", "Last Updated", 100);
column.setAlignment(HorizontalAlignment.RIGHT);
column.setDateTimeFormat(DateTimeFormat.getFormat("MM/dd/yyyy"));
configs.add(column);

ListStore<Stock> store = new ListStore<Stock>();
store.add(stocks);

cm = new ColumnModel(configs);

ContentPanel cp = new ContentPanel();
cp.setBodyBorder(true);
cp.setHeading("Basic Grid");
cp.setButtonAlign(HorizontalAlignment.CENTER);
cp.setLayout(new FitLayout());
cp.getHeader().setIconAltText("Grid Icon");
cp.setSize(600, 300);

grid = new Grid<Stock>(store, cm);
grid.setStyleAttribute("borderTop", "none");
grid.setAutoExpandColumn("name");
grid.setBorders(false);
grid.setStripeRows(true);
grid.setColumnLines(true);
grid.setColumnReordering(true);
grid.getAriaSupport().setLabelledBy(cp.getHeader().getId() + "-label");
cp.add(grid);

ToolBar toolBar = new ToolBar();
toolBar.getAriaSupport().setLabel("Grid Options");

toolBar.add(new LabelToolItem("Selection Mode: "));
final SimpleComboBox<String> type = new SimpleComboBox<String>();
type.getAriaSupport().setLabelledBy(toolBar.getItem(0).getId());
type.setTriggerAction(TriggerAction.ALL);
type.setEditable(false);
type.setFireChangeEventOnSetValue(true);
type.setWidth(100);
type.add("Row");
type.add("Cell");
type.setSimpleValue("Row");
type.addListener(Events.Change, new Listener<FieldEvent>()
{
public void handleEvent(FieldEvent be)
{
boolean cell = type.getSimpleValue().equals("Cell");
grid.getSelectionModel().deselectAll();
if (cell)
{
grid.setSelectionModel(new CellSelectionModel<Stock>());
}
else
{
grid.setSelectionModel(new GridSelectionModel<Stock>());
}
}
});
toolBar.add(type);

cp.setTopComponent(toolBar);

add(cp);

new QuickTip(grid);
}


public void refreshGrid()
{
//remove all and add slowly leaks IE memory.
// grid.getStore().removeAll();

//attempt at removing each item individually -- still leaks
while(grid.getStore().getCount() > 0)
{
grid.getStore().remove(0);
}
grid.getStore().add(stocks);


}
}

private static class Stock extends GenericGridItem
{

private Stock()
{
this("name");
}

private Stock(String name)
{
super();
super.set("name", name);
super.set("symbol", "test");
super.set("last", "test");
super.set("change", 100.0);
super.set("date", "test");
}
}


Please let me know if you require any further information.

GXT Version: 2.2.4
GWT Version: 2.3.0