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 <jfbaldwi..arthlink.net> 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 <jfbaldwi..arthlink.net>
>> 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?
>
>
This archive was generated by hypermail 2.0.0 : Fri Sep 18 2009 - 10:47:26 EDT