PDA

View Full Version : Expanding Tree node causes out of memory



darkling235
18 Apr 2011, 5:02 AM
I'm trying to build a tree. But the first time I open any node it spins forever and it throws an OOM exception. I must be configuring something wrong but I'm not sure what. I am setting the children list and I set the parent for each node (that has children or a parent)

This is my stack trace:




08:49:11.445 [ERROR] [scalebasemanagement] exception thrown
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.ensureCapacity(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at com.extjs.gxt.ui.client.widget.treegrid.TreeGrid.setExpanded(TreeGrid.java:381)
at com.extjs.gxt.ui.client.widget.treegrid.TreeGrid.onDataChanged(TreeGrid.java:694)
at com.extjs.gxt.ui.client.widget.treegrid.TreeGrid$2.storeDataChanged(TreeGrid.java:151)
at com.extjs.gxt.ui.client.store.StoreListener.handleEvent(StoreListener.java:28)
at com.extjs.gxt.ui.client.store.StoreListener.handleEvent(StoreListener.java:1)
at com.extjs.gxt.ui.client.event.BaseObservable.callListener(BaseObservable.java:178)
at com.extjs.gxt.ui.client.event.BaseObservable.fireEvent(BaseObservable.java:86)
at com.extjs.gxt.ui.client.store.TreeStore.onLoad(TreeStore.java:761)
at com.extjs.gxt.ui.client.store.TreeStore$1.loaderLoad(TreeStore.java:156)
at com.extjs.gxt.ui.client.event.LoadListener.handleEvent(LoadListener.java:23)
at com.extjs.gxt.ui.client.event.LoadListener.handleEvent(LoadListener.java:1)
at com.extjs.gxt.ui.client.event.BaseObservable.callListener(BaseObservable.java:178)
at com.extjs.gxt.ui.client.event.BaseObservable.fireEvent(BaseObservable.java:86)
at com.extjs.gxt.ui.client.data.BaseTreeLoader.onLoadSuccess(BaseTreeLoader.java:129)
at com.extjs.gxt.ui.client.data.BaseTreeLoader.onLoadSuccess(BaseTreeLoader.java:1)
at com.extjs.gxt.ui.client.data.BaseLoader$1.onSuccess(BaseLoader.java:127)
at com.extjs.gxt.ui.client.data.RpcProxy$1.onSuccess(RpcProxy.java:36)
at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.onResponseReceived(RequestCallbackAdapter.java:216)
at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:393)
at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:157)
at com.google.gwt.dev.shell.BrowserChannel.reactToMessagesWhileWaitingForReturn(BrowserChannel.java:1714)
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:165)

sven
18 Apr 2011, 8:24 AM
java.lang.OutOfMemoryError: Java heap space

You need to increase your heap space

darkling235
18 Apr 2011, 9:34 AM
I don't see how I can be running out of heap memory unless I've set something up with my data and or configuration. The whole tree only has about 15 nodes.

darkling235
19 Apr 2011, 3:44 AM
I increased my memory to over a gig but no dice and that should easily be enough memory for a 15 item tree. Every time I try to open a node it spins for about 20 seconds and then the browser stops responding. about 20 seconds after that it throws its exception. It really feels like some kind of infinite loop.

This is my code



//TreeGrid
public class ManagementPanel extends VerticalPanel {

public ManagementPanel() {

ContentPanel cp = new ContentPanel();

cp.setWidth(ScaleBaseManagement.SCREEN_WIDTH);

cp.setHeading("ScaleBase Management");

ManagementToolBar toolBar = new ManagementToolBar();

cp.setTopComponent(toolBar);

final DescriptionTab descriptionTab = new DescriptionTab();

RpcProxy<List<DatabaseServer>> proxy = new RpcProxy<List<DatabaseServer>>() {
@Override
protected void load(Object loadConfig,
AsyncCallback<List<DatabaseServer>> callback) {

UserIdentification ui = LoginData.getInstance().getUserId();

ServerListAsync serverList = (ServerListAsync) GWT
.create(ServerList.class);
serverList.getServersListByAPI(ui, "", callback);

}
};

TreeLoader<DatabaseServer> loader = new BaseTreeLoader<DatabaseServer>(
proxy);
List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
//final CheckBoxSelectionModel<DatabaseServer> sm = new CheckBoxSelectionModel<DatabaseServer>();

/*sm.addSelectionChangedListener(new SelectionChangedListener<DatabaseServer>() {
@Override
public void selectionChanged(
SelectionChangedEvent<DatabaseServer> se) {
SelectedServers.getInstance().addAll(se.getSelection());
descriptionTab.setSelection(se.getSelection());
}
});*/
//sm.setSelectionMode(SelectionMode.MULTI);
//columns.add(sm.getColumn());

ColumnConfig cc = new ColumnConfig();
cc.setId("shardId");
cc.setHeader("ID");
cc.setWidth(100);
cc.setRenderer(new TreeGridCellRenderer<DatabaseServer>());
columns.add(cc);

cc = new ColumnConfig();
cc.setId("addr");
cc.setHeader("IP Address");
cc.setWidth(200);
columns.add(cc);

cc = new ColumnConfig();
cc.setId("port");
cc.setHeader("Port");
cc.setWidth(100);
columns.add(cc);

cc = new ColumnConfig();
cc.setId("type");
cc.setHeader("Database Type");
cc.setWidth(100);
columns.add(cc);

cc = new ColumnConfig();
cc.setId("status");
cc.setHeader("Status");
cc.setWidth(100);
columns.add(cc);

cc = new ColumnConfig();
cc.setId("active");
cc.setHeader("Active");
cc.setWidth(100);
columns.add(cc);

cc = new ColumnConfig();
cc.setId("readReplica");
cc.setHeader("Read Replica");
cc.setWidth(100);
columns.add(cc);

cc = new ColumnConfig();
cc.setId("failover");
cc.setHeader("Failover");
cc.setWidth(100);
columns.add(cc);

//loader.setRemoteSort(false);

final SortInfo sortInfo = new SortInfo("shardId", SortDir.ASC);
final TreeStore<DatabaseServer> store = new TreeStore<DatabaseServer>(
loader);

loader.addLoadListener(new LoadListener() {
@Override
public void loaderLoad(LoadEvent le) {
store.sort(sortInfo.getSortField(), sortInfo.getSortDir());
}
});

ColumnModel cm = new ColumnModel(columns);
TreeGrid<DatabaseServer> grid = new TreeGrid<DatabaseServer>(store, cm);

grid.setHeight(150);
grid.setStripeRows(true);
//grid.setSelectionModel(sm);

loader.load();

cp.add(grid);

add(cp);

/*TabPanel tabPanel = new TabPanel();
tabPanel.setWidth(ScaleBaseManagement.SCREEN_WIDTH);

// MonitoringTab monitoring = new MonitoringTab();
ServerGraphs monitoring = new ServerGraphs();
tabPanel.add(monitoring);

TabItem events = new TabItem("Events");
tabPanel.add(events);

tabPanel.add(descriptionTab);

tabPanel.setHeight(400);

add(tabPanel);*/

}
}

//model
public class DatabaseServer extends BaseTreeModel implements Serializable {
private static final long serialVersionUID = 8237194722880846935L;

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getServerId();
return result;
}

@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DatabaseServer other = (DatabaseServer) obj;
if (getServerId() != other.getServerId())
return false;
return true;
}

public DatabaseServer() {

}

public DatabaseServer(int shardId, int serverId, String name,
String ipAddress, int status) {
setShardId(shardId);
setServerId(serverId);
setName(name);
setIp(ipAddress);
setStatus(status);
}

public int getShardId() {
return (Integer) get("shardId");
}

public void setShardId(int shardId) {
set("shardId", shardId);
}

public int getServerId() {
return (Integer) get("serverId");
}

public void setServerId(int serverid) {
set("serverId", serverid);
}

public String getName() {
return get("name");
}

public void setName(String name) {
set("name", name);
}

public void setUserName(String userName) {
set("userName", userName);
}

public String getUserName() {
return get("userName");
}

public String getIp() {
return get("ip");
}

public void setIp(String ip) {
set("ip", ip);
set("type", "MySQL");
String url = getIp();
String addr = getIp();
String port = "3306";

int indexOfAddr = url.indexOf("://");
int indexOfPort = url.lastIndexOf(":");

try{
if (indexOfPort > indexOfAddr) {
addr = url.substring(indexOfAddr + 3, indexOfPort);
port = url.substring(indexOfPort + 1);
} else
{
if(indexOfAddr != -1)
addr = url.substring(indexOfAddr + 3);
}
}catch(StringIndexOutOfBoundsException e)
{
}

set("addr", addr);
set("port", port);
}

public void setUrlParameters(String urlParameters) {
set("urlParameters", urlParameters);
}

public String getUrlParameters() {
return get("urlParameters");
}

public void setActive(Boolean active) {
set("active", active);
}

public Boolean isActive() {
return get("active");
}

public void setReadReplica(Boolean readReplica) {
set("readReplica", readReplica);
}

public Boolean isReadReplica() {
return get("readReplica");
}

public void setFailoverEnabled(Boolean failoverEnabled) {
set("failover", failoverEnabled);
}

public Boolean isFailoverEnabled() {
return get("failover");
}

public ServerStatusType getStatus() {
int status = (Integer) get("status");
return ServerStatusType.values()[status];
}

public void setStatus(int status) {
set("status", status);
}
}


//Data provider method
@Override
public List<DatabaseServer> getServersListByAPI(UserIdentification ui,
String parent) throws Exception {

if (logger.isLoggable(Level.FINEST))
logger.finest("User " + ui.getUserId()
+ " attempts to get servers list");
if (SessionManager.getInstance().getUserSession(ui) == null)
throw new Exception("Unauthorized access");

List<DatabaseServer> databaseServers = new ArrayList<DatabaseServer>();

ServersServiceProxy proxy = new ServersServiceProxy();
ServersServiceStub serversService = proxy.getProxy();;
if(serversService == null)
{
logger.log(Level.SEVERE, "Could not access Web service");
return new ArrayList<DatabaseServer>();
}

GetAllInstances param = new GetAllInstances();
param.setCustomerName(ui.getCustomerId());

ServersServiceStub.Database[] databases = serversService.getAllInstances(param).get_return();

try {
if (databases != null)
{
HashMap<Integer, DatabaseServer> map = new HashMap<Integer, DatabaseServer>();
for (Database database : databases)
{

if(database.getParentId() != 0)
{
DatabaseServer db = ModelUtils.fromDatabase(database);
db.setParent(map.get(database.getParentId()));
map.get(database.getParentId()).getChildren().add(db);
}
else
{
map.put(database.getId(), ModelUtils.fromDatabase(database));
}
}
databaseServers.addAll(map.values());
}
} catch (Exception e) {
logger.log(Level.SEVERE, "", e);
}

return databaseServers;
}
}


Can anyone see what I'm doing wrong? Given the tiny size of the tree I have to assume I'm misconfiguring something and causing some kind of loop in the tree code.
Thanks

darkling235
20 Apr 2011, 2:51 AM
Also if the code has all been converted to Javascript, what part of the application can actually throw an OOM exception?