Understanding the memory model / structure of Java is essential in fine tuning the JVM settings and to find out what causes the dreaded java.lang.OutOfMemory Error. In Java, the memory is divided into Heap memory and Non Heap Memory. The Non heap memory is actually two types – The method area or the PermGen and the Native memory. The method area or PermGen is logically part of the Heap memory. But complete freedom is given in the JVM spec to implement it as Non Heap or part of Heap to different JVM implementations.
The spec says – “The method area is created on virtual machine start-up. Although the method area is logically part of the heap, simple implementations may choose not to either garbage collect or compact it. This version of the Java virtual machine specification does not mandate the location of the method area or the policies used to manage compiled code”
Many popular JVM’s implement it outside the Heap memory area and there by not subjecting it to Garbage Collection and Compaction. Few others implement it as part of Heap and is subjected to Garbage Collection.
The heap holds the Object data, Method Area / PermGen holds the class code and the per -class runtime constant pool. All class data are loaded into this ( Method Area / PermGen) memory space. This includes the field and method data and the code for the methods and constructors.
We will NOT look into what happens in the Native memory area as it is very difficult to find documentation on what goes there. Typically it is best left to the people who are creating a Java Virtual Machine. As developers, we are mostly interested in the Heap and the Method Area as shared memory structures and of course the stack memory which is not shared and owned by individual threads. Each thread gets its own stack area.
The heap is divided into different regions to help the garbage collection process efficient and faster. The Heap is broadly divided into an Young Generation Space and the Old or Tenured Generations area. The young space is further divided into Eden and Survivor spaces. When objects are first allocated (new) they are stored in the Eden Space. When the object is in use for specific time or duration of the Garbage Collection Cycle, the object gets moved from the Eden to the Survivor Space. When it ages further it is promoted to the Old Generation or Tenured Space. This mechanism ensures that there are enough space freed up for new or short lived objects and garbage collector can do an efficient job. The Young Generation is introduced based on the fact that most of the Objects in the life time of a JVM is short lived and only a small percentage actually lives longer. When ever the Garbage collector frees up objects in the Young generation, it is known as a Minor Collection or Minor GC. The Garbage collection happening at the Old Generation or Tenured Generation is known as Major Collection or Major GC.
By seperating objects by their life span allows the minor garabage collection to be shorter, quicker and less cpu intensive. This inturn gives more cpu time to the application. Ideally minor garbage collections should happen and major garbage collections should happen only rarely.
When is java.lang.OutOfMemoryError throw ?
This error is thrown when the JVM cannot allocate the object because there is not enough free memory available and no more memory could be made available free by the Garbage Collector.
How do I know which area of the Java memory structure is responsible for the OutOfMemory Error ?
This is fairly easy. We need to look at the description of the OutOfMemory Exception and it reveals a lot of information. Here is a collection of common OutOfMemory Scenarios and the causes for the same.
a) Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space
There not enough memory to allocate the new object and Garbage collection is unable to free up memory
b) Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Application tried to create an array whose size is bigger than the available free heap size.
c) Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space
There is not enough space in the Method Area / PermGen to allocate or load a new class. Reasons: When application requires a lot of classes for example loading a lot of 3rd party libraries.
d) Exception in thread “main” java.lang.OutOfMemoryError: unable to create new native thread
e) Exception in thread “main”: java.lang.OutOfMemoryError: <reason> <stacktrace> (Native method)
d) and e) are the memory issues happening in the thread exclusive memory areas ( Note that each thread has a PC Register, Java Stack and Native Method stack) d) usually means a new thread couldn’t be created due to the process memory limit. e) usually indicates a memory issue in the Native Method stack.
f) Exception in thread “main”: java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?
There is not enough memory available for the Operating System and may be swap space is too small. Increasing the OS memory or increasing the Swap space can usually rectify this issue
Hope you find this useful. If yes, you can help by sharing this post with your friends on facebook, twitter, google+ and other social media platforms.