2 solution of java.lang.OutOfMemoryError in Java (original) (raw)
Everyone in java development faces java.lang.OutOfMemoryError now and then, OutOfMemoryError in Java is one problem which is more due to the system's limitation (memory) rather than due to programming mistakes in most cases though in certain cases you could have a memory leak which causing OutOfMemoryError. I have found that even though java.lang.OutOfMemoryError is quite common basic knowledge of its cause and the solution is largely unknown among junior developers. Beginners books like Head First Java don't teach you much about how to deal with this kind of error. You need real experience dealing with production systems, handling a large number of user sessions to troubleshoot and fix performance issues like running out of memory.
If you want to be good at troubleshooting and performance analysis, you need to learn some books on Java performance and profiling e.g. Java Performance The Definitive Guide By Scott Oaks or the Java Performance by Binu John. They are an excellent resource for senior Java developers and also teaches you tools and process to deal with an error like java.lang.OutOfMemoryError.
In this article, we will explore what is java.lang.OutOfMemoryError; Why OutOfMemoryError comes in Java application, different type of OutOfMemoryError and How to fix OutOfMemoryError in Java.
This article is purely meant to provide basic knowledge of java.lang.OutMemoryError and won't discuss profiling in detail. For profiling read the books I have mentioned before.
And, if you are serious about improving your advanced JVM skill and learn things like taking and analyzing heap dumps then highly recommend you to join Java Application Performance and Memory Management course on Udemy. It's one of the advanced courses for Java programmers to learn more about Performance and Memory management including troubleshooting memory leaks in Java.
What is java.lang.OutOfMemoryError in Java
OutOfMemoryError in Java is a subclass of java.lang.VirtualMachineError and JVM throws java.lang.OutOfMemoryError when it ran out of memory in the heap. OutOfMemoryError in Java can come anytime in the heap mostly while you try to create an object and there is not enough space on the heap to allocate that object. Javadoc of OutOfMemoryError is not very informative about this, though.
Types of OutOfMemoryError in Java
I have seen mainly two types of OutOfMemoryError in Java:
- The java.lang.OutOfMemoryError: Java heap space
- The java.lang.OutOfMemoryError: PermGen space
Though both of them occur because JVM ran out of memory they are quite different to each other and their solutions are independent of each other.
The difference between "java.lang.OutOfMemoryError: Java heap space" and "java.lang.OutOfMemoryError: PermGen space"
If you are familiar with different generations on the heap and How garbage collection works in java and aware of new, old and permanent generations of heap space then you would have easily figured out this OutOfMemoryError in Java. Permanent generation of the heap is used to store String pool and various Metadata required by JVM related to Class, method and other java primitives.
Since most of the JVM default size of Perm Space is around "64MB" you can easily run out of memory if you have too many classes or a huge number of Strings in your project.
An important point to remember is that it doesn't depend on –Xmx value so no matter how big your total heap size you can run OutOfMemory in perm space. The good thing is you can specify the size of permanent generation using JVM options "-XX: PermSize" and "-XX: MaxPermSize" based on your project need.
One small thing to remember is that "=" is used to separate parameter and value while specifying the size of perm space in the heap while "=" is not required while setting maximum heap size in java, as shown in below example.
export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"
Another reason of "java.lang.OutOfMemoryError: PermGen" is memory leak through Classloaders and it’s very often surfaced in WebServer and application server like tomcat, WebSphere, glassfish or WebLogic.
In the Application server, different classloaders are used to load different web applications so that you can deploy and undeploy one application without affecting other applications on the same server, but while undeploying if the container somehow keeps a reference of any class loaded by application class loader then that class and all other related class will not be garbage collected and can quickly fill the PermGen space if you deploy and undeploy your application many times.
"_java.lang.OutOfMemoryError: PermGen_” has been observed many times in tomcat in our last project, but the solution of this problem are really tricky because first you need to know which class is causing a memory leak and then you need to fix that. Another reason of OutOfMemoryError in PermGen space is if any thread started by the application doesn't exit when you undeploy your application.
These are just some example of infamous classloader leaks, anybody who is writing code for loading and unloading classes has to be very careful to avoid this. You can also use visualgc for monitoring PermGen space, this tool will show the graph of PermGen space and you can see how and when Permanent space getting increased. I suggest using this tool before reaching to any conclusion.
Another rather unknown but interesting cause of "java.lang.OutOfMemoryError: PermGen" we found is the introduction of JVM options "-Xnoclassgc".
This option sometimes used to avoid loading and unloading of classes when there are no further live references of it just to avoid the performance hit due to frequent loading and unloading, but using this option is the J2EE environment can be very dangerous because many frameworks like Struts, spring etc uses reflection to create classes and with frequent deployment and undeployment you can easily run out of space in PermGen if earlier references were not cleaned up. This instance also points out that sometimes bad JVM arguments or configuration can cause OutOfMemoryError in Java.
So the conclusion is to avoid using "-Xnoclassgc" in the J2EE environment especially with AppServer.
Tomcat to Solve OutOfMemoryError in PermGen Space
From tomcat > 6.0 onward tomcat provides a memory leak detection feature that can detect many common memory leaks on a web-app perspective e.g ThreadLocal memory leaks, JDBC driver registration, RMI targes, LogFactory, and Thread spawned by web-apps.
You can check complete details on htp://wiki.apache.org/tomcat/MemoryLeakProtection you can also detect memory leaks by accessing the manager application that comes with tomcat, in case you are experiencing memory leak on any java web-app its a good idea to run it on tomcat.
How to solve java.lang.OutOfMemoryError: Java heap space
- An easy way to solve OutOfMemoryError in java is to increase the maximum heap size by using JVM options "-Xmx512M", this will immediately solve your OutOfMemoryError. This is my preferred solution when I get OutOfMemoryError in Eclipse, Maven, or ANT while building a project because based upon the size of the project you can easily run out of Memory.
Here is an example of increasing maximum heap size of JVM, Also its better to keep -Xmx to -Xms ration either 1:1 or 1:1.5 if you are setting heap size in your java application
export JVM_ARGS="-Xms1024m -Xmx1024m"
- The second way to resolve OutOfMemoryError in Java is rather hard and comes when you don't have much memory and even after increase the maximum heap size you are still getting java.lang.OutOfMemoryError, in this case, you probably want to profile your application and look for any memory leak.
You can also use Eclipse Memory Analyzer to examine your heap dump or you can use any profiler like Netbeans or JProbe. This is a tough solution and requires some time to analyze and find memory leaks.
How to solve java.lang.OutOfMemoryError: PermGen space
As explained in the above paragraph this OutOfMemory error in java comes when the Permanent generation of heap is filled up. To fix this OutOfMemoryError in Java, you need to increase the heap size of the Perm space by using the JVM option "-XX: MaxPermSize".
You can also specify the initial size of Perm space by using "-XX: PermSize" and by keeping both initial and maximum Perm Space you can prevent some full garbage collection that may occur when Perm Space gets re-sized. Here is how you can specify initial and maximum Perm size in Java:
export JVM_ARGS="-XX:PermSize=64M -XX:MaxPermSize=256m"
Some time java.lang.OutOfMemoryError in Java gets tricky and on those cases profiling remains ultimate solution.Though you have the freedom to increase heap size in java, it’s recommended that to follow memory management practices while coding and setting null to any unused references.
That’s all from me on OutOfMemoryError in Java I will try to write more about finding the memory leak in java and using profiler in some other post. Please share what is your approach to solving java.lang.OutOfMemoryError in Java.
Important Note: From Tomcat > 6.0 onward tomcat provides a memory leak detection feature which can detect many common memory leaks on Java applications e.g ThreadLocal memory leaks, JDBC driver registration, RMI targes, LogFactory, and Thread spawned by web apps. You can check complete details on htp://wiki.apache.org/tomcat/MemoryLeakProtection.
You can also detect memory leak by accessing the manager application that comes with tomcat, in case you are experiencing a memory leaks on any java web app it's a good idea to run it on tomcat to find out the reason of OutOfMemoryError in PermGen space.
Tools to investigate and fix OutOfMemoryError in Java
Java.lang.OutOfMemoryError is a kind of error that needs a lot of investigation to find out the root cause of the problem, which object is taking memory, how much memory it is taking or finding dreaded memory leak and you can't do this without having knowledge of available tools in java space. Here I am listing out some free tools which can be used to analyze heap and will help you to find the culprit of the OutOfMemoryError
1. Visualgc
Visualgc stands for Visual Garbage Collection Monitoring Tool and you can attach it to your instrumented hotspot JVM. The main strength of visualgc is that it displays all key data graphically including class loader, garbage collection, and JVM compiler performance data.
The target JVM is identified by its virtual machine identifier also called as vmid. You can read more about visualgc and vmid options here.
2. jmap
The jmap tool is a command line utility comes with JDK6 and allows you to take a memory dump of the heap in a file. It’s easy to use as shown below:
jmap -dump:format=b,file=heapdump 6054
Here file specifies the name of the memory dump file which is "heap dump" and 6054 is PID of your Java progress. You can find the PDI by using "ps -ef” or windows task manager or by using the tool called "jps"(Java Virtual Machine Process Status Tool).
3. jhat
The jhat tool was earlier known as hat (heap analyzer tool) but it is now part of JDK6. You can use jhat to analyze heap dump file created by using "jmap". The jhat is also a command line utility and you can run it from the cmd window as shown below:
jhat -J-Xmx256m heapdump
Here it will analyze the memory dump contained in file "heapdump". When you start jhat it will read this heap dump file and then start listening on HTTP port, just point your browser into port where jhat is listening by default 7000, and then you can start analyzing objects present in heap dump.
4. Eclipse memory analyzer
Eclipse memory analyzer (MAT) is a tool from the eclipse foundation to analyze the java heap dump. It helps to find classloader leaks and memory leaks and helps to minimize memory consumption. You can use MAT to analyze heap dump carrying millions of objects and it also helps you to extract suspects of memory leak. See here for more information.
5. Books to learn Profiling
As your Java experience grows, expectation also grows in terms of niche skills like analyzing performance issues and being comfortable with profiling. You won't normally learn those skills unless you take extra effort.