This memory leak search began when I was qualifying code that scrolls
through thousands of BufferedImages. Of course, only a small
fraction of these images are displayed at any given time, so the code
has occasion to create new BufferedImages for the ones being
displayed and to dispose of the unused, out-of-view instances. I
think that it is worth mentioning that each BufferedImage is owned by
a Component that is responsible for painting the image.
The problem I observed is an out-of-control growth of the Java heap.
To confirm that there was a leak, I limited the size of the heap
using the -Xmx64m command line argument (which limits the heap to
64MB). Initially, my testing showed that Java would throw an
"OutOfMemoryException" as it failed to reclaim the RAM it had
allocated for the BufferedImage instances. It was easy to see this
transpire, as I had also enabled versbose garbage collector output by
way of the "-verbose:gc" command line argument.
Frustrated with running out of RAM in a garbage-collected runtime
environment, I then began to dig deeper. I added print statements to
the "finalize()" method of the Component class that paints a
BufferedImage instance. The Components were being collected, and the
finalize method was being called, and it nulled out the
BufferedImage, but still the memory was not being reclaimed by the GC
and I was geting"OutOfMemoryExceptions. Next, I used
java.lang.ref.WeakReferences and a java.lang.ref.ReferenceQueue to
see if the GC was collecting the actual BufferedImages. In fact it
was, but still, the OutOfMemoryExceptions were being thrown.
What made the difference was having the Component class' "finalize()"
method explicitly call "flush()" on its BufferedImage before nulling
it out. Once this was done, the verbose output from the GC confirmed
that the BufferedImage's memory was being reclaimed and the
OutOfMemoryException stopped.
To date, I have run let the code run for over 24 hours, and the heap
size (as reported by verbose output from the GC) remains fairly
consistent.
I hope this helps to shed some light on the situation.
Regards,
-Mike Ellis
On Mar 29, 2006, at 8:50 AM, Michael Hall wrote:
On Mar 29, 2006, at 7:21 AM, Michael Ellis wrote:
when I added this call to the "finalize()" method of the owning
Class,
How did you do this? Because I am not able in what I have done to
duplicate your results. I just tried moving the flush() call I was
explicitly doing to the finalize method and it makes no difference
Runtime free memory change is 0. How are you determining that the
flush() call is freeing or improving memory. Runtime is not always
the best, maybe you are figuring this out differently?
=========================
Michael F. Ellis
President
Ellis Softworks Inc.
----------
Phone: (941) 713-0361
Email: email@hidden
Web: http://www.ellissoftworks.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden