These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Memory scalability when using list() and EHCache
PostPosted: Tue Sep 12, 2006 1:06 pm 
Newbie

Joined: Tue Sep 12, 2006 10:54 am
Posts: 3
Hibernate version: 1.3.1

Code between sessionFactory.openSession() and session.close():

Code:
List output = session.createCriteria( ... )
.add(Restrictions.eq( ... ))
.setCacheable( true )
.list();


Full stack trace of any exception that occurs:

no errors, exceptions, or warnings. no functionality problems at all.

Hello,

I'm using Java 1.5, Hibernate 3.1.3, annotations, and EHCache 1.1 with overflowToDisk="false" (query cache and second level cache are on).


I call something like this:

Code:
List output = session.createCriteria( ... )
.add(Restrictions.eq( ... ))
.setCacheable( true )
.list();



In the example above, assume that everything was ALREADY cached in the query cache and in the second level cache.

So, in the example above, the .list() function would just return a copy of the data in the second level cache (keyed on the data in the query cache). Right?

Instead of getting a COPY of the data in the second level cache, can I just get references directly to the data in the second level cache?

In other words, since I won't be changing anything returned from .list() function, I don't want a COPY of the data because I'm running out of memory. I want the data itself, not a copy of the data.

thank you for your help,

VT_Hokies


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 12, 2006 6:39 pm 
Newbie

Joined: Wed Jun 30, 2004 2:02 am
Posts: 13
The second-level cache doesn't store fully-formed objects, it stores object properties, so there is no way to do what you're asking.

If you're worried about memory usage in a particular scenario, use scroll() instead of list(), or bypass the cache, or drop down and do batch SQL.


Top
 Profile  
 
 Post subject: ty
PostPosted: Wed Sep 13, 2006 10:00 am 
Newbie

Joined: Tue Sep 12, 2006 10:54 am
Posts: 3
Thank you very much for responding! Your response was very helpful and I appreciate it very much.

anders wrote:
The second-level cache doesn't store fully-formed objects


Ah. That is news to me.


You suggested:
1. scroll()
2. bypass the cache.
3. batch SQL.


1. I thought about doing this and was saving it for a last resort. It will probably be what I end up doing.

2. This won't save memory in the place I'm trying to save memory. In my specific case, I have many users all calling list() at the same time. They'll all create a memory issue after calling list() a few times.

3. batch SQL? Do you mean .setFirstResult().setMaxResults().list()? I assume that'll create a different entry in the query cache for each part of the results. That sounds interesting, but shouldn't be very different from using scroll().
I assume you don't mean the @BatchSize annotation. I think that's only for insert/update.

Thanks again,

VT_Hokies


Top
 Profile  
 
 Post subject: Re: ty
PostPosted: Wed Sep 13, 2006 3:08 pm 
Newbie

Joined: Wed Jun 30, 2004 2:02 am
Posts: 13
VT_hokies wrote:
1. I thought about doing this and was saving it for a last resort. It will probably be what I end up doing.

This is a viable approach if you only need to process the results and then move on. If you need to transmit all that data back to another piece of code or another client (that is, you need to close the session before the real consumer of the data gets involved), then it's at best a useful but not sufficient technique for memory scalability. In other words, building another large data structure from each row of your scrolled results set will just push the scalability problem to another part of the code. It's a complex problem...

VT_hokies wrote:
2. This won't save memory in the place I'm trying to save memory. In my specific case, I have many users all calling list() at the same time. They'll all create a memory issue after calling list() a few times.


Sounds like a variant of what I describe above.

VT_hokies wrote:
3. batch SQL? Do you mean .setFirstResult().setMaxResults().list()? I assume that'll create a different entry in the query cache for each part of the results. That sounds interesting, but shouldn't be very different from using scroll().
I assume you don't mean the @BatchSize annotation. I think that's only for insert/update.


Sorry -- that was probably a little too obtuse of a reference. I'm referring to doing things like .createQuery("update x where ...").executeUpdate(). Whether that approach makes any sense is completely application and situation dependent, of course. It also leads to cache coherency issues, so there are complications to using that approach.

The firstResult/maxResult approach (what I know/think of as paging) can be very helpful as long as the data consumer knows about and cooperates in the paging. In a sense it's more powerful than scroll, for the reason I described above: if all we do with our scrolled result set is build another huge data structure, then all we've accomplished is to push the bubble in the linoleum to a different spot on the floor.

anders


Top
 Profile  
 
 Post subject: Re: ty
PostPosted: Mon Sep 18, 2006 1:43 pm 
Newbie

Joined: Tue Sep 12, 2006 10:54 am
Posts: 3
anders wrote:
if all we do with our scrolled result set is build another huge data structure, then all we've accomplished is to push the bubble in the linoleum to a different spot on the floor.


Yes, I completely understand your analogy here but I want to try using scroll() anyways.

Anyways, it seems like scroll() doesn't use the QueryCache at all. It also seems like it's only partly using the SecondLevelCache (things go in, but things don't get taken back out).

I'm making these statements mostly from what I see in SessionFactory.getStatistics() but it also jives with what happens when I time my code (and when I skim through parts of the Hibernate source code).

I can't find this documented anywhere online (in the forums or the documentation). Isn't that kind of important to know?

Code:
ScrollableResults results = session.createCriteria(Class.forName(className))
        .add(Restrictions.eq( ... ))
        .setCacheable(true)
        .scroll(ScrollMode.FORWARD_ONLY); //getQueryCacheHitAndMissCount() don't change and secondLevel.getHitAndMissCount() don't change.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.