Skip to main content

Memory leak problem

13 replies [Last post]
jacarma
Offline
Joined: 2008-09-19

Hello,
we are having memory problems using phoneME advanced. We are using the version for Windows Mobile Personal Profile Davy compiled. We have tested with bn91 and bn96.

I wrote a minimum test, you can download it here:
https://correo.prodevelop.es/descarga/mobile/phoneme/Animation.java

It's a simple double buffered animation. When I run this application more and more memory is being used for the application until there is no free memory. In some PDAs the OS hangs or the VM.

¿Is this a bug or is there something I am not doing well?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
jacarma
Offline
Joined: 2008-09-19

Thank you very much Davy.

davyp
Offline
Joined: 2007-01-03

I spent some time looking into the issue, and I think I may have identified the cause of the
memory leak problem. Here is what happens:

-when calling getGraphics() on an AWT component peer, a new PPCGraphics java object is
instantiated and returned
-at the same time a native AwtGraphics object is allocated in ppcgraphics.cpp
-this native memory is only released when calling Graphics.dispose()
-you can call this method yourself in your application code or
-you can wait for the garbage collector to call finalize() which in turn calls dispose()

Now, I think the memory leak is caused by the fact that the native AwtGraphics object upon
creation has a JNI NewGlobalRef to the PPCGraphics java object. This reference is only
released with DeleteGlobalRef when calling PPCGraphics.dispose(). Now as long as this method
is not called, there will be a reference to the PPCGraphics java object and the garbage collector
will not call PPCGraphics.finalize() and hence not the dispose() method.

This basically means that if the programmer does not call the dispose method on the Graphics
object, that a reference to the object will remain and the garbage collector will not reclaim the
memory. I think that either the global reference has to go, or that we have to split the
PPCGraphics class into two classes so that the global reference will point to a second class,
and the finalization of the first class will trigger the dispose of the second class.

Does this make sense?

Davy

davyp
Offline
Joined: 2007-01-03

I eliminated the JNI global reference to the PPCGraphics object, and the memory leak issue
seems to be resolved. At least the Animation example code runs fine now without any
modification.

I did have to change several things in the PocketPC Graphics peer, so you may want to take the
new b101 build on my website for a test run first. Let me know if you still have issues with the
gvSIG application.

Davy

jacarma
Offline
Joined: 2008-09-19

Thank you,
I downloaded from your site phoneME Advanced - Personal Profile b102 for Windows Mobile 5 but I have tried the animation program again and it still uses more and more memory.

davyp
Offline
Joined: 2007-01-03

Are you sure that it is still a memory leak, i.e. memory that is not garbage collected?
I ran your application for more than an hour and with a tool to measure the memory
use I noticed that memory allocation of the CVM.exe process will not go beyond
4.6 MB.

Due to the native graphics peer implementation, there is a continues allocation of objects, but
now they should be garbage collected (which they weren't before). So you may see a memory
increase on the heap space up to about a megabyte or so before the garbage collector kicks
in. Trying to avoid the memory allocation cycle too is not straightforward.

Davy

jacarma
Offline
Joined: 2008-09-19

I'm going to test it again.
Javi

jacarma
Offline
Joined: 2008-09-19

I think you are right, in my PDA, taskmanager says the animation uses between 5,35MB and 6MB and no more. I will test it with gvSIG Mobile.

Thank you

jacarma
Offline
Joined: 2008-09-19

I feel Warnocked[1]

[1]http://en.wikipedia.org/wiki/Warnocked

davyp
Offline
Joined: 2007-01-03

Dear Jacarma,

I will try to see if I can reproduce the problem, but fixing it may take
a bit longer. I did not notice your first posts because the posts on
this forum did not make it into my inbox. For some reason the bridge
between the forum and the corresponding mailing list no longer works.

EDIT: I can confirm the memory leak.

Davy

davyp
Offline
Joined: 2007-01-03

I have been trying to figure out what was wrong, and I have found the cause of the memory leak
but not the reason why the leak occurs. In your code, you have an endless loop in the
constructor which calls:
this.getGraphics().drawImage(image, 0,0,null);

The getGraphics() call returns a Graphics object. For each call, the corresponding peer
PPCGraphics allocates native resources (including memory for native objects). This causes a
rapid increase of memory allocation in the beginning, but this should not be a problem, because
these native resources are cleaned up in the finalize method of the PPCGraphics object. So if
the object is garbage collected, then the allocated resources should be freed.

But for some reason, the object is never finalized (and I don't know why as there should not be
any reference anymore to the Graphics object during the following iteration. I would appreciate it
if somebody can tell me how I can debug the fact that the finalize method is never called in the
PPCGraphics object.

As a workaround, I don't get the memory leak if I release the resources myself by changing your
code into:
Graphics g1 = this.getGraphics();
g1.drawImage(image, 0,0,null);
g1.finalize();

Perhaps it is better to replace g1.finalize() with g1.dispose() because the finalize() method
should only be called by the garbage collector and not by our own code (the finalize() method
calls the dispose() method which releases the allocated native memory). You could also
move the Graphics g1 = this.getGraphics(); outside the while loop and remove the
g1.finalize(); line.

So if anyone can tell how to debug the finalize() issue, let me know.

Davy

ebresie
Offline
Joined: 2003-08-06

Could this be one of the conditions described here

http://java.sun.com/developer/technicalArticles/javase/finalization/

???

Eric

davyp
Offline
Joined: 2007-01-03

Thanks Eric for the article, but I already found and read it before posting about the issue
on this forum. While interesting, it did not help me much with identifying the cause of
the problem.

Davy

jacarma
Offline
Joined: 2008-09-19

We can't recommend to use gvSIG Mobile on top of PhoneME (and we'll love It) because we know the PDA memory will be filled in 10 or 20 minutes in all cases and then it will crash.

Can anybody just confirm this memory leak is a bug?