-Sekhar Chandraju
The java.lang.OutOfMemoryError is the subclass of java.lang.VirtualMachineError which is thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.
When we encounter a java.lang.OutOfMemoryError, it is not always the best idea to analyze Java heap dumps. We first need to investigate the root cause of the java.lang. OutOfMemoryError. Only after the root cause is identified we can decide whether or not to analyze Java heap dumps.
Obviously, memory is the exhausted resource for a java.lang.OutOfMemoryError. Unfortunately, the Java specification of java.lang.OutOfMemoryError does not elaborate further on what kind of memory it's talking about
There are six different types of runtime data areas, or memory areas, in the Java Virtual Machine.
Program Counter Register:
Program Counter Register:
The Program Counter Register, also known as the pc register, stores the address of the Java byte code instruction that is currently being executed (just like the processor register in our central processing). java.lang.OutOfMemoryError is not thrown from the pc register since a program counter is not conventionally considered as a memory.
Java Virtual Machine Stack:
Java Virtual Machine Stacks contain frames where data, return values, and partial execution results are stored. These can be expanded during runtime. If there's not enough memory for the expansion of an existing Java Virtual Machine stack, or for the creation of a new Java Virtual Machine stack for a new thread, the Java Virtual Machine will throw a java.lang.OutOfMemoryError.
Heap:
The Heap is where instances of Java classes and arrays are allocated. A java.lang.OutOfMemoryError will be thrown when there is not enough memory available for instances of Java classes or arrays.
Native Method Stack:
Native Method Stacks store conventional stacks, also known as C stacks, to support native methods that are written in a non-Java language such as C/C++. Native memory stacks can be expanded during runtime. If there's not enough memory for the expansion of an existing native memory stack or for the creation of a new native memory stack for a new thread, you would see a java.lang.OutOfMemoryError.
Method Area:
The Method Area stores class-related information, the runtime constant pool, for instances, the code for methods and constructors, and field/method data. If there's not enough memory in the method area, you will encounter java.lang.OutOfMemoryError.
Runtime Constant Pool:
The Runtime Constant Pool contains constants such as field references and literals. A java.lang.OutOfMemoryError will be thrown when not enough memory is available for the construction of the runtime constant pool area
Types of Error messages:
Now we have understood which memory areas throw java.lang.OutOfMemoryError. We will see types of OutOfMemoryError and their root causes
java.lang.OutOfMemoryError: Requested array size exceeds VM limit -- This error message indicates that there is a memory request for an array but that's too large for a predefined limit of a virtual machine. We need to check the source code to make sure that there's no huge array created dynamically or statically. Fortunately, latest virtual machines usually do not have this limit.
java.lang.OutOfMemoryError: PermGen space -- We will see an OutOfMemoryError when the Permanent Generation area of the Java heap is full, like the above message. we can just use the -XX:MaxPermSize command-line option to increase the maximum limit of the permanent generation. For example, -XX:MaxPermSize=128m will set the maximum size of the permanent generation to 128 Mbytes
java.lang.OutOfMemoryError: requested NNN bytes for MMMM. Out of swap space?
Literally you could check the operating system configuration for swap space. It seems that the Java Virtual Machine is not sure if the swap space is the root cause of the problem (?).We can check whether this Java Virtual Machine is consuming too much native memory .We also need to make sure there's enough memory for this JVM and no other processes are consuming most of memory resource. The last thing we can try is to find any known defects related to the module, MMMM.
java.lang.OutOfMemoryError: unable to create new native thread -- This kind of message is seen when you have an excessive number of threads or if the native memory is exhausted and a thread is attempting to be created.
Exception in thread "main" java.lang.OutOfMemoryError
at sun.misc.Unsafe.allocateMemory (Native Method) – In this message there's no clue whether it's native memory or a Java heap. But “sun.misc.Unsafe.allocateMemory (Native Method)" indicates that it might be native memory related.
at sun.misc.Unsafe.allocateMemory (Native Method) – In this message there's no clue whether it's native memory or a Java heap. But “sun.misc.Unsafe.allocateMemory (Native Method)" indicates that it might be native memory related.
java.lang.OutOfMemoryError: JVMCI046: allocateMemory failed -- In the following case, the Java virtual machine is kind enough to tell us that there's native memory exhaustion. In the message, the Java virtual machine says "allocateMemory failed" which means a native memory allocation failed:
If you find that heap space is the root cause for OutOfMemoryError, then we can dive into heap analysis. Before doing that we have to get the Java Heap Dump.
Java Heap Dump:
A Java heap dump is a snapshot of a Java heap at a specific time. A Java heap dump is usually automatically generated by the Java Virtual Machine, but you can also force Java heap dump generation. You can find Java heap dumps in the current working directory of the Java Virtual Machine process. Heap analyzers have to be used to read Java heap dumps.
Heap Analyzer:
Heap analyzer tools like IBM Heap Analyzer, HAT, jhat, alphaWorks etc., are used to analyze the heap dump. The first thing to analyze is memory leak. Memory leaks can be because of a static variable, local variable or local thread.
Memory leak patterns:
· Horizontal memory leak: Many objects are referenced from same objects. The following picture shows the simulation of horizontal memory leak using Heap analyzer.
· Vertical memory leak: Many objects are linked together. The following picture shows the simulation of vertical memory leak using Heap analyzer.
· Diagonal memory leak: Combination of horizontal and vertical memory leak. It's often found in tree structures. The following picture shows the simulation of diagonal memory leak using Heap analyzer.
·
· Diagonal memory leak: Combination of horizontal and vertical memory leak. It's often found in tree structures. The following picture shows the simulation of diagonal memory leak using Heap analyzer.
Conclusion:
We've investigated different patterns of java.lang.OutOfMemoryError, artifacts and their possible solutions. When we see a java.lang.OutOfMemoryError and find Java heap dumps; however, it's not always necessary to analyze Java heap dumps. We often find many people blindly jumping on Java heap dumps without looking into other information. We can't diagnose all kinds of problems by analyzing the Java heap dumps alone. Java heap dumps are just snapshots of Java heap at specific times. Garbage collection trace is another source of information where we can figure out what's going on with the Java heap and garbage collector.
First, we need to determine whether java.lang.OutOfMemoryError is caused by Java heap, native memory or something else from error messages. If it's caused by native memory, we need to utilize operating system memory monitoring tools provided by an operating system such as svmon on AIX operating systems or your favourite third-party tools. If java.lang.OutOfMemoryError is related to Java heap, we need to make sure that the Java heap and parts of the Java heap are configured well enough to handle a given workload by analyzing garbage collection trace. If your JVM needs a little bit more Java heap and you have extra memory, you could endow more memory to the Java Virtual Machine in order to increase heap capacity, for example, by increasing the -Xmx command-line option. If you've already reached the address space limit, you could redistribute the workload with multiple horizontal clones of the Java Virtual Machine. If you really suspect there's Java heap leak, you are more than welcome to analyze the Java heap dumps with any of your favourite Java heap analysis tools.
No comments:
Post a Comment