Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java memory mystery (do I have a leak)?

I have a standalone Java problem running in a linux server. I started the jvm with -Xmx256m. I attached a JMX monitor and can see that the heap never really passes 256Mb. However, on my linux system when I run the top command I can see that:

1) First of all, the RES memory usage of this process is around 350Mb. Why? I suppose this is because of memory outside of the heap?

2) Secondly, the VIRT memory usage of this process just keeps growing and growing. It never stops! It now shows at 2500Mb! So do I have a leak? But heap doesn't increase, it just cycles!

Ultimately this poses a problem because the swap of the system keeps growing and eventually the system dies.

Any ideas what is going on?


The important question I want to ask, what are some scenarios that this could be a result of my code and not the JVM, kernal, etc. For example, if the number of threads keeps growing, would that fit the description of my observations? Anything similar that you can suggest me to look out for?

like image 708
erotsppa Avatar asked Sep 25 '09 03:09

erotsppa


People also ask

How do I know if I have a memory leak?

The system can have a myriad of symptoms that point to a leak, though: decreased performance, a slowdown plus the inability to open additional programs, or it may freeze up completely.

Are memory leaks in Java rare?

Memory leaks are unusual in the case of memory-efficient programs. The Java Garbage Collector does the job of freeing up memory occupied by unused objects in the program.

How do I fix a memory leak in Java?

If you see that your memory increases in the 'Monitor' tab, try pressing 'Perform GC' (garbage collection) and see if that decreases memory usage. Now go back and comment out most of the code of your program to the point where the application just start & stops. Repeat until the application doesn't leak at all.


2 Answers

A couple of potential problems:

  • Direct allocated buffers and memory mapped files are allocated outside of the Java heap, and can't conveniently be disposed.
  • An area of stack is reserved for each new thread.
  • Permanent generation (code and interned strings) is outside of the usual stack. It can be a problem is class loaders leak (usually when reloading webapps).
  • It's possible that the C heap is leaking.

pmap -x should show how your memory has disappeared.

like image 155
Tom Hawtin - tackline Avatar answered Oct 06 '22 09:10

Tom Hawtin - tackline


Swap Sun vs IBM JVM to test


  1. RES will include code + non-head data. Also, some things that you think would be stored in the heap aren't, such as the thread stack and "class data". (It's a matter of definition but code and class data are controlled by -XX:MaxPermSize=.)

  2. This one sounds like a memory leak in either the JVM implementation, the linux kernel, or in library JNI code.

If using the Sun JVM, try IBM, or vice versa.

I'm not sure exactly how dlopen works, but code accessing system libraries might be remapping the same thing repeatedly, if that's possible.

Finally, you should use ulimit to make the system fail earlier, so you can repeat tests easily.

like image 20
DigitalRoss Avatar answered Oct 06 '22 08:10

DigitalRoss