tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ken Bowen <kbo...@als.com>
Subject Re: memory leak
Date Thu, 21 Jan 2010 03:10:59 GMT
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 <kbowen@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-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>


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


Mime
View raw message