What Are Memory Leaks in Java? And How to Find Them
Optimize your application’s performance by effectively managing resources, especially memory resources. Prevent, identify, or eliminate memory leaks within your java applications before they affect your application, business, and the user experience.
What causes memory leaks in java?
The ingrained memory management tool in Java, known as Java Virtual Machine or JVM, handles the process of garbage collection, which includes finding and removing unused objects in order to efficiently manage memory allocation. However, the garbage collector can only detect and remove unreferenced java objects, so memory leaks may still occur in java applications when object references are no longer needed but are still being maintained.
Common scenarios that lead to memory leaks include:
Static fields and collections
The life cycle of a static variable exists through the duration of the application, remaining in memory until the application ends. Since static fields and collections are excluded from garbage collection and require deliberate clean-up, they are often the culprit of memory leaks. Mutable static fields should be avoided during programming.
Similar to a static variable, thread local variables are overlooked by the garbage collector due to the thread being considered active as a member in the thread class. If threads are continuously pooled and kept alive, garbage collection will ignore the associated thread-local variables, contributing to a potential memory leak.
Complex and circular object structures:
Circular or complex bi-directional references might be too complicated for the garbage collector to detect. These leaks can also be particularly difficult to track down without a thorough understanding of each piece of code or a heap analysis; sometimes the existence of an element such as a child object can prevent an associated document or nodes from being removed even if they were deleted.
How to find memory leaks
Java memory leaks can result in fatal application crashes if they are not identified and addressed promptly. Monitor memory usage and mitigate Java application memory leaks with the following techniques and profiling tools:
Common scenarios to find memory leaks include:
One very common sign of memory leaks is the java.lang.OutOfMemoryError message. Investigate further for detailed messages that may provide additional clues. For instance:
Java heap space may indicate a memory leak, that the specified heap size is too low, or that your finalizer queue is overloaded.
PermGen space means that the area that stores method and class objects is full. This can be remedied by using -XX:MaxPermSize to increase the space.
Requested array size exceeds VM limit is evidence that an array that is greater than the heap size is being assigned.
<Reason> <stack trace> (Native method) indicates that a native method was unable to be allocated the necessary amount of memory.
Request <size> bytes for <reason>. Out of swap space? is a notice that the native heap is near capacity or that a local heap allocation failed.
Verbose garbage collection
Enabling verbose garbage collection is an effective and efficient way to detect a memory leak. For a detailed look at garbage collection, add the -verbose:gc parameter to the JVM configuration of your Java application to view summary reports that provide a better understanding of memory utilization.
How to prevent memory leaks
Thoroughly understanding and carefully reviewing your application code is a programming best practice that has benefits that extend beyond preventing or identifying memory leaks. Avoid shortcuts that could undermine your efforts in the future.
Hear from our customers
"The ability to trace a transaction visually and intuitively through the interface was a major benefit that AppDynamics delivered. This visibility was especially valuable when Nasdaq was migrating a platform from its internal infrastructure to the AWS Cloud."
Heather Abbott, Senior Vice President of Corporate Solutions Technology, Nasdaq