As I mentioned, the DAO class uses a standard try/catch/finally pattern to ensure that all statements, resultsets, & connections have been closed before a method returns.

On Jan 20, 2010, at 9:25 PM, Travis Beech wrote:

I would make sure that your DAO class is closing any statements,
resultsets, and connections that are no longer being used once your
method call returns.

Since GC does happen immediately your db resources could still be in
memory.

Travis Beech

On Jan 20, 2010, at 3:50 PM, Ken Bowen <kbo...@als.com> wrote:

Short version: I have a project which gets some simple info from a
db via DWR, and outputs it simply on the page.  There is a memory
leak on the java side.

Longer version:
I've developed a project using JSPs and the Ajax tool DWR 2.0
(Direct Web Remoting: http://directwebremoting.org/dwr).
I've used Java 1.6, and am running the project on Tomcat 6.0.20 on a
remote CentOS 5 VPS with 288MB memory.  {I know that my problem may
lie in my (mis)use of DWR, but I'm starting here to clarify my
(possible lack of) understanding about JSP memory usage and Tomcat.}

The app consists of a number of independent tasks, one of which
(LISTALL) just asks for a list of all the html web pages (about 550)
available from a certain collection.  The payload shipped to the
browser is roughly 140K, just consisting of a list of authors and
titles and urls to the relevant pages.

Using top, I've observed that when I repeatedly run this LISTALL
request, the resident memory increases about 1Meg for every
approximately ~10 reloads of the page.  If I turn of javascript in
the browser and repeatedly reload the page, there is no change in
the resident memory (as naturally expected).  It is suggestive the
140k * 10 is in the ballpark of 1Meg.

The LISTALL request is contained in the javascript for onPageLoaded
() on a very simple JSP page which simply displays the data,
together with some Amazon and Google ads.

The LISTALL request simply makes a call
StoriesAccess.getAllAuthorsAndTitles through the DWR servlet:

  http://<mydomain>/dwr/call/plaincall/
StoriesAccess.getAllAuthorsAndTitles.dwr

The StoriesAccess class contains no instance variables and consists
of a collection of methods to be invoked for their callbakcs (the
dwr servlet makes the return values of the methods available to the
javascript as a callback).  The getAllAuthorsAndTitles is very
simple:  It makes several calls to the (MySQL) db to obtain the
data, and assembles a bean which it returns.
Basically:
  public AuthorsWithTitles getAllAuthorsAndTitles(long userNum)
  {
           // the data bean to be returned
      AuthorsWithTitles result = new AuthorsWithTitles("all");

           // db call to get all the story data
      CustomSbDataDAO csbddao = new CustomSbDataDAO();
      List<Story> alist = csbddao.retrieveStoryAll();

          // holds individual "author + titles" classes being
assembled:
      HashMap<Integer,AuthorAndTitles> hres = new
HashMap<Integer,AuthorAndTitles>();

      Iterator<Story> stories = alist.iterator();
      while (stories.hasNext()){
          Story story = stories.next();
          Integer authorNum = story.getAuthorNum();

          AuthorAndTitles aat = hres.get(authorNum);
          if (aat == null){
              Author author = csbddao.retrieveAuthorByPrimaryKey
(authorNum);
              aat = new AuthorAndTitles(authorNum,
author.getAuthorLN(), author.getAuthorFN());
              hres.put(authorNum, aat);
          }
          XStory xstory = new XStory(story);
          aat.addStory(xstory);
      }
          // this will be the actual list of "author + titles"
returned:
      ArrayList<AuthorAndTitles> initATs = new
ArrayList<AuthorAndTitles>();
      initATs.addAll(hres.values());

          // sort by author, and sub-sort by assigned title letter
of story:
      Collections.sort(initATs,  new Comparator<AuthorAndTitles>()
{...comparator....} );
      Iterator<AuthorAndTitles> aTs = initATs.iterator();
      while (aTs.hasNext()){
          AuthorAndTitles at = aTs.next();
          List<XStory> xstoryList = at.getAuthorStories();
          Collections.sort(xstoryList,    ...comparator...);
      }

      result.setAuthorsWithTitles(initATs);
      return result;
  }

The class CustomSbDataDAO provides methods for accessing MySQL, and
all connections, statements, resultsets, etc., are released using
the standard try/catch/finally pattern.   It's my understanding
(belief) that each time the method runs, when it returns, the values
in all the local variables become available for gc.

So the obvious issue is where the leak could be occurring.  DWR is
relatively mature and somewhat extensively used, so there isn't
likely to be simple-minded memory leak in DWR itself.  Any
suggestions for where to look or what I may be doing wrong will be
greatly appreciated.

Thanks in advance,
Ken


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to