This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Finding memory leaks


On Sat, 2004-02-28 at 18:40, Rutger Ovidius wrote:
> I'd be very interested to hear what you find out, if anything.
> 
> Does your app collect properly with sun's java?

I haven't tried this out since I wiped out the last memory leaks that
were truly found in my app ... But actually it would be a good idea
to check this ...

In the meantime I added my own simple mark algorithm to my heap
analyzing Perl script. The results after a few days of debugging are
not very clear, however. What I observe is:

  1) Statistics: After 4 few days of running the RSS of my processes
     is 22MByte - /proc/*/maps tells me that the data segment is 19MB.
     GC_dump() lists 10MByte memory in the free list and 4.5MByte
     blocks in use. When going through the blocks and counting each
     object's size I end up with 1.3MBytes memory used. 700MBytes of
     this is - after my mark algorithm - not in use but still marked
     by gcj's garbage collector. A very small amount of memory (haven't
     even bothered counting) is blacklisted.

  2) Many of the objects that are marked by both my mark algorithm and
     gcj's garbage collector are pointed to by some nested data
     structure that do not constitute Java  objects - I haven't found
     out yet what this is is. Maybe some internal list used for
     incremental garbage collection?

  3) No idea why the garbage collector does not collect the objects that
     are not marked by my algorithm. Mostly they seem to be objects
     that were only allocated locally in a method or even loop. I'm
     doing the inspection after hours of idling - I don't think the
     garbage collector just haven't had enough time for collecting ...

     Maybe the garbage collector decides to stop collecting because
     with actually 70% free blocks it's not really necessary to spend
     time on collection - however, this makes things extremely difficult
     to debug and might be a problem for my app that does just nothing
     for long time periods (hours) and then gets very active (regarding
     memory allocation) for a few seconds or minutes and goes idling
     again, after. Maybe the garbage collector just isn't collecting
     fast enough during "active" periods and refuses to collect
     when there were time to do it?

  4) After having a closer look at some un-collected objects and
     comparing them to the ones that were collected I started

	- declaring classes defined locally within other classes
          "static" wherever possible in order to avoid objects being
	  linked with their "parents"

	- use local variables rather than instance variables wherever
 	  this is possible.

	- keep the lifetime of objects with pointers to other objects
	  as short as ever possible.

      This seems to reduce the number of objects that actually stay
      uncollected. But this is rather a feeling than a proven fact ... I
      see that the same code may allocate objects that are "immediately"
      collected while from time to time some objects seem to get "lost"
      somehow and are not collected ... sometimes they are collected
      when I have a look at the heap hours later.

      For instance I used to put some Thread objects into a Vector
      and regularly (all 30seconds) I had a loop going through this
      Vector, wiping out Threads that weren't active any more. One
      of this Thread derived classes had a char[16384] allocated in an
      instance variable. I saw that randomly but rather often these
      char[] were not collected even after the object was removed from
      my Vector. After allocating the char[] within the run() method
      rather than the instance variable there are still some rare
      cases where a stray object is left marked on the heap but it's
      not a big problem any more. In the meantime I gave up my Vector,
      too ...

   5) The total heap size seems to be slowly (well, not constantly, 
      but in increasingly large chunks) increasing though the amount
      of memory in use currently stays more or less the same (started
      at about 900kBytes, after 4 days it's now 1.3Megs). Of course,
      this is the "idle" state of my app. From time to time it's doing
      some work and temporarily uses 3-4Mbytes - mostly in many very
      small objects, but also allocating some 4-32kByte buffers. No
      idea, why the heap keeps growing - maybe due to fragmentation?
      Maybe due to the garbage collector not collecting fast enough?
      I don't know. Unfortunately, my way of debugging is not "real
      time" capable - I just can do "heap shots" at arbitrary moments.

      Sooner or later the application just crashes - probably due to
      memory problems.

   6) Unfortunatley I haven't found any way to switch GC debugging on
      with gcj. I assume the backtrace function would enlighten me
      on why GC does keep the objects I can find no reference to marked.

   7) Up to now I have not been able to reproduce any of these effects
      with simple test programs. In my test cases all the objects always
      get collected as expected :-(

So after long nights of debugging I am pretty sure that my app is not
leaking - at least not significantly. Anyway, my app's memory is
growing, anyway, over time. I would have preferred to find some silly
bug in my program rather than not actually understanding what the hell
is going on.

Best regards,
Tom
----------------------------------------------------------------------------
Thomas Aeby, Kirchweg 40, 1735 Giffers, Switzerland, Voice : (+41)26
4180040
Internet: aeby@graeff.com                           PGP public key
available
----------------------------------------------------------------------------
One way to stop a runaway horse is to bet on him. 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]