Finding Java memory leak (using JNA)

My Java application seems to have a memory leak. This is the first time that I have been doing something like this. I am not using pure Java nor JNA to use user32 functionality. I noticed that when my program runs for a longer time, like one hour, the memory that its need for the process continues to grow. It looks like 100Mb when I start it and it ended up exceeding 1GB after an hour.

I noticed this using Windows Task Manager. When I started researching this, I used profilers like visualvm and JProfiler. Both showed me a heap usage of about 150mb and about 20mb of PermGen space, all the time Windows Task Manager clearly showed me it was using about 1GB. So I figured the problem must be on the native heap, which both visualvm and JProfiler seem to be unable to access / profile. I created heaps of memory dumps and snapshots and parsed them using visualvm and MAT. The largest objects (and their saved sizes) have never exceeded 4MB - I'm not an expert at all, but that doesn't seem very leaky / not too big to me. Plus when I do garbage collection manually (using profilers) the java heap used has decreased as expected,but the total process consumption remained at 1 GB. These findings also led me to conclude that the problem is not in the area of ​​the Java heap.

So I think the JNA calls are causing these problems. But unfortunately I don't know how to solve this issue as I can't just use JNA. I've read tons of articles about memory leaks, most of which are jave related, almost always ignore the native heap. Those that don't (like the oracle article) tell me that I can't just use one of the native profiling methods because they misinterpret Java code and lead to wrong conclusions. Oracle offers "libumem.so", but this apparently can only be used on tanning systems.

So my general question is, can someone give me some hint on what to do? What tools can I use?

But maybe the problem is that I just am not using JNA correctly. According to this: https://groups.google.com/forum/#!topic/jna-users/Xy7Sm8Fb-Gc and from what I read and understood from a few pieces of text from stackoverflow, jna documentation and random article numbers on the internet is is that JNA will release the allocated memory and the allocated memory on the java side will be garbage collected. So when I do the following:

    //I want to get text (as a String) of a handle
    public static String getTextOfHWND(HWND hwnd)
    {
      //allocate the space for the string
    byte[] windowText = new byte[512];
    //let user32 method fill me the byte array with the needed information
    User32.INSTANCE.SendMessageA(hwnd, WM_GETTEXT, 100, windowText);
    //let Native convert this to a String I can use in Java
    String whatWasFound = Native.toString(windowText);


    return whatWasFound;
    }

      

... the variable "byte [] windowText" (allocated memory for it) should be freed by the GC, the same should be true for the string I receive ("whatWasFound"). It's right? Do I need to do something manually in this example? I see that Native offers a free method for buffers (but unfortunately not for arrays). What happens on the native side, does something get highlighted there and is it freed later?

Any help is appreciated.

+3


source to share





All Articles