1. Sounded like a good first step. 2. You have two basic options. Kick the objects out of the DataContext or replace the entire DataContext.
To kick the objects out of the DataContext, I think you want unregisterObjects(Collection objects), but it might be invalidateObjects(Collection objects). I think unregisterObjects() gives them the boot and invalidateObjects() keeps them around, but flushes the cache (they become HOLLOW). I could have that wrong, though. :-) I'd try unregisterObjects() first. If you are done with everything in the thread/session DataContext, you can always replace it. BaseContext.bindThreadObjectContext(DataContext.createDataContext()) or BaseContext.bindThreadObjectContext(null). Setting it to null might not be as safe if anything needs it after you null it out in that request. I suspect the latter will be the easiest for you ... On Fri, Sep 18, 2009 at 10:04 AM, Joe Baldwin <[email protected]> wrote: > Michael, > > You have made some good points. I was reconsidering my design last night > and coincidentally you came up with some of the same criticisms that I did > (and more). > >> I used a singleton that controlled access to my shared objects. I don't >> know how well that will scale since I didn't have to worry about scalability >> (I had 3-5 users searching large amounts of data). I also don't remember if >> DataContext is thread safe (what would happen it two different threads did a >> performQuery() on the same DataContext). I'm pretty sure I made my access >> methods on my singleton "synchronized" to keep it safe. (Again, don't know >> how well that will scale.) > > > I was reconsidering this approach last night as well. I pictured having an > Application scoped DataContext with 500 and it seemed reasonable, but then > when I pictured one with 5000 products (and possibly faults associated with > associated DataObjects) it started to appear to be not such a good design > approach. > >> The easiest (and probably cheapest at this point) thing is still going to >> be to add RAM. > > > Well, I think I agree with you and bumping the Tomcat Xmx up to 256MB is > the first thing I am going to change. I also think that I am going to go > with your idea of not using a cache strategy on the large result sets (like > the product searches). I am going to continue to use paging of 50 objects > similar to what you are using. > > Questions: > 1. Please let me know if this last paragraph sounds reasonable or if I > missed any of your recommendations. > 2. Could you please verify for me how to properly release the memory of a > "read-only" result set within the scope of one session. (i.e. There might be > 10-20 fetches and each new one will render the previous one unnecessary, so > I would like to GC it on the fly, unless that is a bad idea). So with the > new BaseContext weak references do I need to simply set the reference to the > ArrayList (aka result set) to null, or do I need to explicitly release the > DataObjects some other way. > > Thanks for all the help, I think these last two questions should be it. > Joe > > > > > > > On Sep 18, 2009, at 9:24 AM, Michael Gentry wrote: > >> On Fri, Sep 18, 2009 at 12:10 AM, Joe Baldwin <[email protected]> >> wrote: >>> >>> That is pretty much what I was wanting to do (after listening to all the >>> input). However, I am not sure how to implement this design in a webapp >>> with >>> session and a Cayenne filter that is creating the DataContext for me >>> (automagically as they say). >> >> >> The one created through the Cayenne filter is the session-based one. >> Cayenne doesn't stop you from creating your own DataContexts to use >> elsewhere (that are separate from the session-based one): >> >> DataContext dc = DataContext.createDataContext(); >> >> >>> I suspect if I implement this sort of simple design (as about 95% of the >>> result sets will be "read-only"), I could probably manage the memory much >>> better. >>> >>> So how do I create a shared context? Is this going to be associated with >>> an >>> Application scoped singleton? >> >> >> I used a singleton that controlled access to my shared objects. I >> don't know how well that will scale since I didn't have to worry about >> scalability (I had 3-5 users searching large amounts of data). I also >> don't remember if DataContext is thread safe (what would happen it two >> different threads did a performQuery() on the same DataContext). I'm >> pretty sure I made my access methods on my singleton "synchronized" to >> keep it safe. (Again, don't know how well that will scale.) >> >> >>> Also how do I create the smaller contexts and >>> make sure they are GC'd after the session is terminated? >> >> >> DataContext dc = DataContext.createDataContext(); >> >> >> The easiest (and probably cheapest at this point) thing is still going >> to be to add RAM. Seriously, what is the price difference between 128 >> MB and 256 MB with your hosting provider? And then compare that >> difference to the cost of man hours trying to shave a few MB off your >> memory footprint. If it takes you 4 man weeks to shave 50 MB (wild >> guess) off your memory footprint, how many months of hosting at 256 MB >> vs 128 MB will that buy you? > >
