Re: Memory Management using Tomcat

From: Michael Gentry (mgentr..asslight.net)
Date: Fri Sep 18 2009 - 10:46:52 EDT

  • Next message: John Armstrong: "Re: Cayenne-3: Core JAR Files"

    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