Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak in a Java web application

Tags:

I have a Java web application running on Tomcat 7 that appears to have a memory leak. The average memory usage of the application increases linearly over time when under load (determined using JConsole). After the memory usage reaches the plateau, performance degrades significantly. Response times go from ~100ms to [300ms, 2500ms], so this is actually causing real problems.

JConsole memory profile of my application: application memory profile

Using VisualVM, I see that at least half the memory is being used by character arrays (i.e. char[]) and that most (roughly the same number of each, 300,000 instances) of the strings are one of the following: "Allocation Failure", "Copy", "end of minor GC", all of which seem to be related to garbage collection notification. As far as I know, the application doesn't monitor the garbage collector at all. VisualVM can't find a GC root for any of these strings, so I'm having a hard time tracking this down.

Memory Analyzer heap dump: heap dump, unreachable memory

I can't explain why the memory usage plateaus like that, but I have a theory as to why performance degrades once it does. If memory is fragmented, the application could take a long time to allocate a contiguous block of memory to handle new requests.

Comparing this to the built-in Tomcat server status application, the memory increases and levels off at, but doesn't hit a high "floor" like my application. It also doesn't have the high number of unreachable char[].

JConsole memory profile of Tomcat server status application: enter image description here

Memory Analyzer heap dump of Tomcat server status applicationp: enter image description here

Where could these strings be allocated and why are they not being garbage collected? Are there Tomcat or Java settings that could affect this? Are there specific packages that could be affect this?

like image 907
Kevin Kibler Avatar asked Nov 20 '12 23:11

Kevin Kibler


People also ask

Is it possible to leak memory in Java?

One of the core benefits of Java is the JVM, which is an out-of-the-box memory management. Essentially, we can create objects and the Java Garbage Collector will take care of allocating and freeing up memory for us. Nevertheless, memory leaks can still occur in Java applications.

What is memory leak and how does Java handle it?

A Memory Leak is a situation where there are objects present in the heap that are no longer used, but the garbage collector is unable to remove them from memory, and therefore, they're unnecessarily maintained. A memory leak is bad because it blocks memory resources and degrades system performance over time.

How do I find a memory leak on an application?

To find a memory leak, you've got to look at the system's RAM usage. This can be accomplished in Windows by using the Resource Monitor. In Windows 11/10/8.1: Press Windows+R to open the Run dialog; enter "resmon" and click OK.


2 Answers

I removed the following JMX configuration from tomcat\bin\setenv.bat:

set "JAVA_OPTS=%JAVA_OPTS% 
    -Dcom.sun.management.jmxremote=true 
    -Dcom.sun.management.jmxremote.port=9090
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false"

I can't get detailed memory heap dumps anymore, but the memory profile looks much better: enter image description here

24 hours later, the memory profile looks the same: enter image description here

like image 168
Kevin Kibler Avatar answered Oct 05 '22 17:10

Kevin Kibler


I would suggest to use memoryAnalyzer for analyzing your heap, it gives far more information.
http://www.eclipse.org/mat/ there is a standalone application and eclipse embedded one. you just need to run jmap on your application and analyze the result with this.

like image 22
Zamir Avatar answered Oct 05 '22 16:10

Zamir