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