Java Memory leaks are caused by the stagnated objects that exhaust the memory resources leaving no working memory space for the new objects. This blog helps you understand Java Memory Leak, its causes, prevention techniques, and fixing in detail.
Java Memory Leaks – Basic concept
Memory efficiency is the crucial factor for any program that is intending for better performance. A Memory efficient program consumes as little memory as possible during the operation. 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. The Garbage Collector (GC) can only remove unreferenced objects, so the referenced objects cannot be removed even if they are no longer helpful for the application. These referenced objects which are no longer helpful to the application runtime pile up and exhaust the memory resources which eventually leads to a Memory Leak in Java.
Should You Worry About Java Memory Leaks?
Memory Leaks in Java are often considered an indication of poorly written programs. Sometimes java resource leaks involve a minimal amount of memory resources that may not seem troublesome to you. However, you must suspect a Memory Leak when your application returns a java.lang.OutOfMemoryError.
If you want everything to be perfect, you should examine every Java Memory Leak you come across. Can Memory Leak in Java be a severe issue?. Yes, Memory Leak in java is bad because it blocks the memory resources with objects that are not useful but still referenced. As time progresses, those objects will gradually decrease the system’s performance.
Memory leakage in java will also lead to the exhaustion of the memory resources, and the system may terminate with a java.lang.OutOfMemoryError. Hence, Java Memory leak leads to slower system performance, crashes, and faults in running programs, and your system may hang.
Even though the system reboot frees up the memory, it leads to a Memory Leak once a faulty program runs again. Mostly the Garbage Collector runs only when there is less available Memory than what your program needs or when the system is slow. Moreover, if the GC does not free up enough space, the program must take Memory from the Operation System.
However, a Java Memory Leak is not as severe as the memory leaks in other programming languages like C++. The size of the Leak and the lifetime of a program are two main factors that you should be concerned about in the case of a Memory Leak.
- A continuously running program, in due course, runs out of memory resources if there is a memory leak, even if it is a small leak. Hence Memory Leak can be a problem if your java application has to run continuously.
- Memory Leak can happen when your program calls a large number of temporary objects that are memory-hogging, and the memory resources get exhausted when they are not de-referenced.
Also Read: What is Java Buffer pool in Memory Space?
Symptoms of Java Memory Leaks
You can notice the following signs if your java application suffers from a Memory Leak.
- Gradually decreasing application performance.
- Continuous increase in usage of Memory during the lifespan of an application.
- Frequent and strange application crashes.
- Application returning OutOfMemoryError
How to Prevent Java Memory Leaks?
In order to prevent memory leaking in Java, remember the following things while writing code.
- Prevent Static Field Holding on to the Object Reference: Usage of the static field should be paid close attention to. Declaring any heavy objects as static links their lifecycle to the lifecycle of the JVM itself, and the entire object graph becomes impossible to collect.
- Prevent Calling String.intern() on Long String: Interned strings are stored in PermGen Space, its size has to be increased to perform a lot of operations on large strings. Using java 8 where Meta Space replaces PermGen space can prevent OutOfMemoryError when using intern on Strings.
- Closing Unclosed Streams: We need to remember to close the unclosed streams manually. Otherwise, you can make use of the auto-close feature in java-8.
- Closing Unclosed Connections: We need to close Unclosed Connections in a disciplined manner.
- Excluding Objects with no hashCode() and equals() into a HashSet: It’s important to provide the hashCode() and equals() implementations in order to make it clear for the GC to reclaim the working memory.
- Do not store a massive amount of data in the session.
- Time-out sessions when they are no longer needed.
- Use StringBuilder and do not create unnecessary objects.
- Avoid String concatenation and do not use the system.GC() method.
How to Avoid Java Memory Leaks?
Following are the steps that can help you to avoid Memory Leaks in Java.
1. Using Reference objects to avoid memory leaks
2. Using java.lang.repackage allows you to avoid direct referencing objects and use special reference objects that the Garbage Collector can quickly clear.
Let’s see how Garbage Collector acts upon different reference objects to avoid memory leaking in java.
- SoftReference object: When the memory runs low, the Garbage Collector has to clear all SoftReference objects.
- PhantomReference object: Manually cleaning up all PhantomReference objects and references as the GC cannot clean them up.
- WeakReference object: All the references to weakly referenced objects are closed when the Garbage Collector finds them.
3. Avoiding Memory Leaks Related to a WebApp Classloader
Memory Leak happens if your code keeps referring to a WebApp classloader. GC cannot remove a classloader unless nothing else refers to it. But all the classes hold a reference to their classloader. As a result, the classloader cannot be removed by the Garbage Collector.
Daemon threads and Static fields are two types of Leaks in this case. Daemon threads are prone to memory leaks as these threads have to refer to the classloader that started the threads, i.e, thread-local memory leak.
4. Other Steps to Avoid Memory Leaks in Java
- Make sure that you close the Statement and ResultSet when you need to.
- For each session, keep the time-out time low.
- Store only the necessary data in your HTTP session.
- Release the sessions when they are no longer needed. HttpSession.invalidate() allows you to do this.
- When you use stmt = con.prepareStatement(SQL query) within a loop, be sure to close it inside that particular loop.
How to create memory leaks in java?
Here’s a simple program to create a true memory leak in Java. (memory leaks in java example)
In the above example,
- We created two vector objects.
- Passed a large valued number.
- Run the program.
In the output it shows java.lang.OutOfMemoryError as the creation of a large vector caused out of memory issue. In case if the program prints the statement, there is no memory leak in this program, ensuring that the program is running successfully.
Detecting and Fixing Memory Leaks
There are many tools to detect memory Leaks in java.
- Visual VM
Following are the Solutions to Fix Memory Leaks
There are many JVM Tools that can optimize the code and show the memory status. We can fix memory Leaks by using them.
- Using the Eclipse framework to get memory leak warnings. It also shows the errors whenever it comes across any causes of memory leak.
- Using Heap Dump: Heap dump is a snapshot of all the objects that reside in the working memory at a certain time. It optimizes the memory usage in the java application.
As a matter of fact, memory leaks happen, and they happen a lot in Java applications. However, it is not unsolvable. We have so many tools which come in handy to avoid and prevent the memory leak before it happens. With all these tools and techniques, you can add worth to java memory management. Ultimately runtime reveals the more complex leaks in the code that are unidentifiable.
We at Seagence help software developers and enterprises with the production and defect monitoring solutions that uncover all defects with the root cause in real-time. Feel free to contact us for your inquiries. Our experts will be in touch within 24 hours and will assist you with the best guidance.