0

listbox Live Data / Loading on Demand with huge data: Out of Memory Issues...

asked 2008-09-02 16:56:48 +0800

christian gravatar image christian
136 2 4

Hi,

we have some lists with quite huge data. We noticed that DataBinding does Loading on Demand, but we have some issues with it.

We want to show several 1000 entries per page. For that we implemented an own BindingListModel that's capable of dynamically load the data.

But it seems ZK builds an empty canvas in the background for each Item, and not only for the visible ones. So i ran into out of memory problems after a few reloads or when the list gets too big (like > 20000 records).

I prepared a sample that demonstrates my problem. You will notice that it takes some time to load it initally and if you do reloads on the page the JVM will suffer on OutOfMemory-Exceptions after the 3rd or 4th reload.

Won't it be possible to change the behaviour that there are only rows / canvases instantiated for visible items?

I think this would solve all my problems...

Any hints / comments?

Setting a pagesize to less < 5000 annoys the users and is not a real option. And there seems to be a Bug with paging: Everything is preloaded and Dynamic loading is not working any more....

Cheers,
chris

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>  
<zk> 
	<window id="mainwin" xmlns:a="http://www.zkoss.org/2005/zk/annotation"> 
		<zscript> 
			public class Person { 
				private String _name; 
				public Person(String name) { 
					_name = name;
				}
				public String getName() { return _name; } 
			} 
			 
			
			public class DataLoaderModel extends AbstractListModel implements BindingListModel {
				//-- ListModel --//
				public int getSize() {
					return 10000;
				}
				public Object getElementAt(int j) {
					System.out.println(j);
					Person personx = new Person("Name "+j); 
					return personx;
				}
				public void sort(Comparator cmpr, boolean ascending) {}
				public int indexOf(Object obj) { return 0; }
			}
			DataLoaderModel model = new DataLoaderModel();
			System.out.println("Hello World");
		</zscript> 
		<div style="height: 100%; position: absolute;"> 
			<listbox width="400px" rows="0" vflex="true" model="@{model}"> 
				<listitem _var="@{person}"> 
					<listcell label="@{person.name}"/>
				</listitem> 
			</listbox> 
		</div> 
	</window> 
</zk> 

delete flag offensive retag edit

20 Replies

Sort by ยป oldest newest

answered 2008-09-03 00:11:38 +0800

robertpic71 gravatar image robertpic71
1275 1

For paging with really huge data you should handle the paging yourself.
Check the Load on Demand Smalltalk.

I prefer small pagesizes (that fit on one page) with short response time. Why do you prefer so big pages?

Note: i have also done, some growing models. They start with an initalsize and growing when the use shows a item i.e. greater 80%.

Here some running demos with 46.000 records:
Growing model with Paging
Growing model with Scrolling/Live Data

However, in my "real life" applications i avoid such huge lists. I offer filters and sortoptions, so that there is no need for such long lists.

/Robert

link publish delete flag offensive edit

answered 2008-09-10 14:39:48 +0800

christian gravatar image christian
136 2 4

Hi again,

Robert inspired me a lot with the Growing Model, thanks to him ;)

But now, just over upgrading to ZK-3.5, it seems the behavior has changed. We now have the "fine" summary bar where pages can be accessed directly and the row counts are summarized.

But it doesn't seem to be able to cope with huge lists. I attached a new sample with a paging size of 50.
The attached sample with a total row count of 30000 shows for the initial view. but if an other user accesses the same page or the same user does a simple reload of the page, the VM (with standard memory settings) runs out of memory. if you increase the row count to 40000 the page never shows up...

Any hints to cope with this?

Thanks,
chris

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="mainwin"?>  
<zk> 
	<window id="mainwin"> 
		<zscript> 
			public class Person { 
				private String _name; 
				public Person(String name) { 
					_name = name;
				}
				public String getName() { return _name; } 
			} 
			 
			
			public class DataLoaderModel extends AbstractListModel implements BindingListModel {
				//-- ListModel --//
				public int getSize() {
					return 30000;
				}
				public Object getElementAt(int j) {
					System.out.println(j);
					Person personx = new Person("Name "+j); 
					return personx;
				}
				public void sort(Comparator cmpr, boolean ascending) {}
				public int indexOf(Object obj) { return 0; }
			}
			DataLoaderModel model = new DataLoaderModel();
			System.out.println("Hello World");
		</zscript> 
		<div style="height: 100%; position: absolute;"> 
			<listbox width="400px" rows="0" vflex="true" model="@{model}" mold="paging" pageSize="50"> 
				<listitem _var="@{person}"> 
					<listcell label="@{person.name}"/>
				</listitem> 
			</listbox> 
		</div> 
	</window> 
</zk> 

link publish delete flag offensive edit

answered 2008-09-25 03:29:24 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

Hi Chris,

Please take a look at this article How to implement paging for listboxes with many items.

link publish delete flag offensive edit

answered 2010-01-31 07:34:53 +0800

fidox gravatar image fidox
21

Hi robertpic71 Im was loooking for a sample like your Growing model with Scrolling/Live Data.

Could you provide me the source code for the growing model with scrolling? Seems nobody wants to use anymore the paging controls but the simple scrolling is better. So the last versions of zk seems not provide that functionality.

Greetings!

link publish delete flag offensive edit

answered 2010-02-01 03:37:56 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

updated 2010-02-01 03:41:58 +0800

Hi fidox,

The growing model with scrolling can automatically be done by ZK5, you can see the demo of the Listbox Live Data(20,000).

link publish delete flag offensive edit

answered 2010-02-03 10:48:50 +0800

fidox gravatar image fidox
21

thank you very much, jumperchen!

I want my listbox grows all available space on the browser. So how can I use rows="0" and live-data at the same time?

By the way, seems this functionality is very unstable? I was trying with 100,000 records and I get a OutOfMemory exception. If the listbox doesn't load records until it's shown why spend a lot of time on starting to display records, and then throws OutOfMemoryExceptions?

Greetings!

link publish delete flag offensive edit

answered 2010-02-04 04:40:47 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

updated 2010-02-04 04:41:05 +0800

Hi,

That is an issue of your server setting , in your case, each object will consume some memories but I think that nobody will design the use case like you did to load 100,000 records per session at the meantime.

link publish delete flag offensive edit

answered 2010-02-04 08:18:53 +0800

RabinRath gravatar image RabinRath
45 1 1

Hi,

I am interested to add some more points here because i am also getting such type of error. User wants to see even >40,000 records in one page without pagination which is possible in simple html. Then why java?? Zk framework??

sample code:

java class:

package ctrl;
import java.util.*;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.*;

public class MyComposer extends GenericForwardComposer {

Listbox listbox;
Grid grid;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);

List<String> items2 = new ArrayList<String>();
for (int j = 0; j < 20000; ++j) {
items2.add("option " + j);
}

listbox.setItemRenderer(new ListitemRenderer() {
@Override
public void render(Listitem item, Object data) throws Exception {
if (data == null) return;

Map<String, String> params = new HashMap<String, String>();
params.put("name", (String) data);

for (int i = 0; i < 10; i++) {
Executions.createComponents("listcell.zul", item, params);
}
}
});

grid.setRowRenderer(new RowRenderer() {
@Override
public void render(Row row, Object data) throws Exception {
if (data == null) return;

String label = (String) data;
for (int i = 0; i < 10; i++) {
row.appendChild(new Toolbarbutton(label + "-" +(i + 1)));
}
}
});
ListModel list = new ListModelList(items2);
listbox.setModel(list);
grid.setModel(list);
}

}

Zul files:

index.zul:

<?xml version="1.0" encoding="UTF-8"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>

<zk xmlns="http://www.zkoss.org/2005/zul"
xmlns:n="http://www.zkoss.org/2005/zk/native">

<window width="1060px" apply="ctrl.MyComposer">
<tabbox width="1100px">
<tabs>
<tab label="Tab 0"/>
<tab label="Tab 1"/>
</tabs>
<tabpanels>
<tabpanel>
<listbox id="listbox" width="1000px" height="500px">
<listhead>
<listheader label="column1" style="width:80px" />
<listheader label="column2" style="width:80px" />
<listheader label="column3" style="width:80px" />
<listheader label="column4" style="width:80px" />
<listheader label="column5" style="width:80px" />
<listheader label="column6" style="width:80px" />
<listheader label="column7" style="width:80px" />
<listheader label="column8" style="width:80px" />
<listheader label="column9" style="width:80px" />
<listheader label="column10" style="width:80px" />
</listhead>
</listbox>
</tabpanel>

<tabpanel>

<grid id="grid" height="500px" width="1000px">
<columns>
<column label="column1" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column2" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column3" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column4" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column5" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column6" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column7" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column8" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column9" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column10" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
</columns>
</grid>
</tabpanel>
</tabpanels>
</tabbox>
</window>
</zk>

listcell.zul:

<listcell>
<toolbarbutton label="${arg.name}-1" /> </listcell>

Observed:

IE6 or IE7 browser hanged and i got Outof memory exception "script error". How is it possible without pagination??? Even Renderer concept also failed here.
If it is a server related setting problem then FYI: i am using this variable in classpath: "-Xms1024m -Xmx1024m" , so how i will solve it??

link publish delete flag offensive edit

answered 2010-02-04 11:34:51 +0800

fidox gravatar image fidox
21

updated 2010-02-04 11:38:12 +0800

Hi!

My problem is a little bit different, I don't want to show a lot of records in a listbox. Im only want to show the records to fit the screen, (30 or 40 records depending of screen resolution).

What I was trying to develop is a single CRUD of one table with 600.000 records. Oviously I don't want to show all these records in a listbox. The user have a simple filter field to lookup what he need. But I can't know the size of the datasource on every invocation. Could be 100.000 or 200.000 records, Why not?

On others frameworks (smartgwt or swing, for example) The view doesn't matter the size of the datasource, They only take the records they need to show and don't touch the others. If the user scroll, the listbox release the old records and store the new items. So we have never OutOfMemory exceptions because in most of cases we haven't more of 100 or 200 records in memory.

But seems zk do something with the datasource before display the sercods. If I increment the size of the datasource the time of listbox loading increments a lot but always show the same records. My datasource implementation is this, to avoid external issues:

public class TestListModel implements ListModel {
	
	@Override
	public Object getElementAt(int index) {
		
		return "value " + index;
	}

	@Override
	public int getSize() {
		return 1000;
	}

	@Override
	public void removeListDataListener(ListDataListener l) {
	}
	
	@Override
	public void addListDataListener(ListDataListener l) {
	}
}

What I can't understand is because the datasource size is so important if at the end I only show 20 or 30 records?

					<listbox id="usersList" rows="10">
						<listhead>
							<listheader label="Id" width="120px" sort="auto" />
						</listhead>
					</listbox>

At the end, what I need is develop a simple CRUD without worry about table record count. The user at the end will decide how use the filter and sortoptions provided by the application.

link publish delete flag offensive edit

answered 2010-02-04 11:47:03 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2010-02-04 11:47:16 +0800

Hi fidox,

therefore you can use the paging mechanism and let them work on database side. There are a few smalltalks about it.

best
Stephan

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2008-09-02 16:56:48 +0800

Seen: 4,212 times

Last updated: Mar 30 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More