Thursday, August 11, 2016

Memory Management in Java

The internals of Java memory model depends on which JVM is used, though at high level things are similar. There are two main memory regions in the JVM - the heap and the stack. Local variables and methods reside on the stack, everything else on the heap.


How many types of memory areas are allocated by JVM?
Many types:
  1. Class(Method) Area
  2. Heap
  3. Stack
  4. Program Counter Register
  5. Native Method Stack
Internal Architecture of JVM
Let's understand the internal architecture of JVM. It contains classloader, memory area, execution engine etc.

1) Classloader
Classloader is a subsystem of JVM that is used to load class files.
2) Class(Method) Area
Class(Method) Area stores per-class structures such as the runtime constant pool, field and method data, the code for methods.
3) Heap
It is the runtime data area in which objects are allocated.
4) Stack
Java Stack stores frames.It holds local variables and partial results, and plays a part in method invocation and return.
Each thread has a private JVM stack, created at the same time as thread.
A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes.
5) Program Counter Register
PC (program counter) register. It contains the address of the Java virtual machine instruction currently being executed.
6) Native Method Stack
It contains all the native methods used in the application.
7) Execution Engine
It contains:
1) A virtual processor
2) Interpreter: Read bytecode stream then execute the instructions.
3) Just-In-Time(JIT) compiler: It is used to improve the performance.JIT compiles parts of the byte code that have similar functionality at the same time, and hence reduces the amount of time needed for compilation.Here the term ?compiler? refers to a translator from the instruction set of a Java virtual machine (JVM) to the instruction set of a specific CPU.


Java Garbage Collection
In java, garbage means unreferenced objects.
Garbage Collection is process of reclaiming the runtime unused memory automatically. In other words, it is a way to destroy the unused objects.

There are methods like System.gc() and Runtime.gc() which is used to send request of Garbage collection to JVM but it’s not guaranteed that garbage collection will happen.
If there is no memory space for creating a new object in Heap Java Virtual Machine throws OutOfMemoryError.

Generally, an object becomes eligible for garbage collection in Java on following cases:
1) All references to that object explicitly set to null e.g. object = null
2) The object is created inside a block and reference goes out scope once control exit that block.
3) Parent object set to null if an object holds the reference to another object and when you set container object's reference null, child or contained object automatically becomes eligible for garbage collection.

Advantage of Garbage Collection

  • It makes java memory efficient because garbage collector removes the unreferenced objects from heap memory.
  • It is automatically done by the garbage collector (a part of JVM) so we don't need to make extra efforts.
Heap Generations for Garbage Collection in Java
Java objects are created in Heap and Heap is divided into three parts or generations for the sake of garbage collection in Java.

  • Young Generation (Eden and Survivor space)
  • Old Generation (Tenured Space)
  • Permanent Generation (permGen)
 Young Generation is further divided into
  • Eden space
  • S0 (survivor space)
  • S1 (survivor space)

Young Generation
Eden space is a place where new objects are created. When the space is filled up to a certain percentage, GC is performed. This event is called as Minor GC.
The surviving objects from Eden space are moved to survivor spaces (S0 & S1).
Minor GC checks the object in survivor spaces and move to other survivor spaces (S0->S1).
Objects surviving multiple minor GC are moved to old generation.

Old Generation
Objects survived multiple minor GC are moved to old generation. When an old generation is full, the major GC takes place to remove the unused objects. This event can cause a minor pause in the working of application. Too many frequent major GC can trigger performance issue in the application. While designing an application, one should be considerate about it.

Perm Gen
Perm Gen contains the metadata of the classes.
  • Methods of a class (including the bytecodes)
  • Names of the classes (in the form of an object that points to a string also in the permanent generation)
  • Constant pool (e.g String pool) information (data read from the class file, see chapter 4 of the JVM specification for all the details).
  • Object arrays and type arrays associated with a class (e.g., an object array containing references to methods).
  • Internal objects created by the JVM (java/lang/Object or java/lang/exception for instance)
When does an object becomes eligible for GC.
  • When a object is not referred by other objects or all its references are set to null.
  • Object moves out of the scope.
  • Weak reference objects, such as WeakHashMap
Note: With Java 8 Perm gen is removed completely. Its replaced by Metaspace. 
Note: Java programmer cannot force the GC from program using System.gc() or Runtime.gc()

Where Java static variables are stored in memory?
Static member variables are stored in Permanent Generation area of heap. The reason is because static doesn’t belong to the object but to the class, so it’s considered as part of class definition.

What is difference between permGen and Metaspace?
In Java 8, permGen is replaced by Metaspace.
There are many difference between them, the major two being:
  • Metaspace can expand at runtime.
  • Metaspace is part of Native memory whereas permGen is part of heap.
 What are different type of Garbage collector?
  • Serial GC (-XX:+UseSerialGC): Serial GC uses the simple mark-sweep-compact approach for young and old generations garbage collection i.e Minor and Major GC. Serial GC is useful in client-machines such as our simple standalone applications and machines with smaller CPU. It is good for smaller applications with low memory footprint.
  • Parallel GC (-XX:+UseParallelGC): Parallel GC is same as Serial GC except that is spawns N threads for young generation garbage collection where N is the number of CPU cores in the system. We can control the number of threads using -XX:ParallelGCThreads=n JVM option. Parallel Garbage Collector is also called throughput collector because it uses multiple CPUs to speed up the GC performance. Parallel GC uses single thread for Old Generation garbage collection.
  • Parallel Old GC (-XX:+UseParallelOldGC): This is same as Parallel GC except that it uses multiple threads for both Young Generation and Old Generation garbage collection.
  • Concurrent Mark Sweep (CMS) Collector (-XX:+UseConcMarkSweepGC): CMS Collector is also referred as concurrent low pause collector. It does the garbage collection for Old generation. CMS collector tries to minimize the pauses due to garbage collection by doing most of the garbage collection work concurrently with the application threads. CMS collector on young generation uses the same algorithm as that of the parallel collector. This garbage collector is suitable for responsive applications where we cannot afford longer pause times. We can limit the number of threads in CMS collector using -XX:ParallelCMSThreads=n JVM option.
  • G1 Garbage Collector (-XX:+UseG1GC): The Garbage First or G1 garbage collector is available from Java 7 and it’s long term goal is to replace the CMS collector. The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector. Garbage First Collector doesn't work like other collectors and there is no concept of Young and Old generation space. It divides the heap space into multiple equal-sized heap regions.
What is java.lang.OutOfMemoryError in Java
OutOfMemoryError in Java is a subclass of java.lang.VirtualMachineErrorand JVM throws java.lang.OutOfMemoryError when it ran out of memory in the heap. OutOfMemoryError in Java can come anytime in heap mostly while you try to create an object and there is not enough space on the heap to allocate that object

Types of OutOfMemoryError
Having this memory architecture in mind also helps to understand the different OutOfMemoryErrors like:
  1. Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space
    Reason: an object could not be allocated into the heap space.
  2. Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space
    Reason: classes and methods could not be loaded into the PermGen space. This occurs when an application requires a lot of classes e.g. in various 3rd party libraries.
  3. Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    Reason: this occurs when an arrays is created larger than the heap size.
  4. Exception in thread “main”: java.lang.OutOfMemoryError: request bytes for . Out of swap space?
    Reason: this occurs when an allocation from the native heap failed and might be close to its limit. The indicates the source of the module where this error occurs.
  5. Exception in thread “main”: java.lang.OutOfMemoryError: (Native method)
    Reason: this error indicates that the problem originates from a native call rather than in the JVM.
Java Heap space:
The JVM's heap stores all the objects generating by a running Java program. Java uses the new operator to create objects and memory for new objects is allocated on the heap at run time. Garbage collection is the mechanism of automatically freeing up the memory contained by the objects that are no longer referenced by the program.

Java Perm space:
Perm space is used to keep information for loaded classes and few other advanced features like String Pool(for highly optimized string equality testing), which usually get created by String.intern() methods. As your application (number of classes) will grow this space shall get filled quickly, since the garbage collection on this Space is not much effective to clean up as required, you quickly get Out of Memory : perm gen space error.

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 Application server different classloaders are used to load different web applications so that you can deploy and undeploy one application without affecting other application on the same server, but while undeploying if container somehow keeps 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. 

How to solve java.lang.OutOfMemoryError: Java heap space
1) 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 project because based upon size of 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"

2) The second way to resolve OutOfMemoryError in Java is rather hard and  comes when you don't have much memory and even after increase 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 use Eclipse Memory Analyzer to examine your heap dump or you can use any profiler like Netbeans or JProbe. This is tough solution and requires some time to analyze and find memory leaks.

How to solve java.lang.OutOfMemoryError: PermGen space
To fix this OutOfMemoryError in Java, you need to increase heap size of Perm space by using JVM option   "-XX: MaxPermSize". You can also specify initial size of Perm space by using    "-XX: PermSize" and keeping both initial and maximum Perm Space you can prevent some full garbage collection which 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"

Tools to investigate and fix OutOfMemoryError in Java
Java.lang.OutOfMemoryError is a kind of error which 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 culprit of 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
Jmap 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 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
Jhat 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". Jhat is also a command line utility and you can run it from cmd window as shown below:

jhat -J-Xmx256m heapdump

Here it will analyze 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 eclipse foundation to analyze 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 object and it also helps you to extract suspect of memory leak.

No comments:

Post a Comment