SyntaxHighlighter

Friday, December 7, 2012

Part 1: Garbage Collection - Basics

Overview:
In java world, Garbage Collection is one of the most important areas which is often overlooked by developers. But its fun to watch when it drives you nut when JVM starts running with low memory or Out Of Memory due to memory leak. Memory leak can happen due to our application or third party libraries or vendor product issue etc…(no one is perfect in this world).

Early this year, despite of having 2GB heap size, our weblogic 10.3.2 server running with JDK1.6_29 was crashing every hour or so due to OutOfMemory error. After spending good amount of time and digging it deeper, we found that it was happening due to huge amount of memory being used by weblogic’s proprietary or default SSL API i.e. “certicom”.
During investigation, I learned a lot about monitoring memory, taking heap dumps and tools to use to browse dump files. I thought of sharing my experience, so that others can benefit from same.

I feel it’s a good idea to start from basics of garbage collections and go further. I have divided this post in 3 part series.

In this series, we will see basics of
  1. Local or instance variables.
  2. Stack Section
  3. Heap Section
  4. Static Section
  5. Garbage Collection.
Introduction:

Local Variables:
Local variables are those which are declared inside the method body including method parameters. Local variables are alive as long as method execution is on the stack OR method reaches to its completion.
For e.g.
public int addOne(int number){
 int sum=number+1;
 return sum;

//number and sum are local variables
}
Instance Variables:
Instance variables are those which are declared within class but outside of any method. Instance variables (could be primitive or reference to another object) live on heap inside the object they belong to.
For e.g.
public class Test{
 private int count;
 private String name;
 private AnOtherObject ref;

//count,name and ref are instance variable.
}
For better memory management, JVM has three different sections called Stack, Heap (Garbage Collectible Heap) and Static where things live.

Stack
  1. Stack section is the place where all local primitive or reference variables and method invocation live.
  2. Each executing thread runs in (or has) its own Stack.
  3. When a method is called, a frame is created on top of stack.
  4. After method is done its execution, frame is popped off the stack and control goes back to the calling method.
  5. If an object is created inside the method body then
    1. creation of that object will happen on the heap.
    2. reference variable will be created on the stack.
    3. linking mechanism will link reference variable (from stack) to the object (on heap).
  6. Variables declared inside the method are NOT visible to any other method on the stack.
  7. As soon as method is popped off the stack, all its local variables, reference variables get flushed away.
Heap 
  1. Heap section is the place where all objects live.
  2. Instance variables (primitive or reference) declared inside the object also live on heap.
  3. If an instance variable is a reference to another object (non-primitive type) then,
    1. reference variable will be created in the referring object.
    2. referred object will be created on heap.
    3. linking mechanism will link reference variable (from heap) to the object (on heap).
Static
  1. Static section is the place where static data or static method lives.
  2. Static fields/methods belong to a class and not tied to specific instance of that class.

For better understanding, Lets look into below example and picture to see logical view of Stack, Heap and Static sections in JVM.

public class Test{
 public void testMe(){
  doSomething();
 }
 
 public void doSomething(){
  int count=0;
  AnotherObject o1=new AnotherObject(5);
  //more code
  doSomeMore();
 }
 
 public void doSomeMore(){
  int x=0;
  AnotherObject o2=new AnotherObject(7);
  //more code
 }
 
 public static void main(String arg[]){
  Test t1=new Test();
  t1.testMe();
 }
}

public class AnotherObject{
 private int a;
 private static status;
 
 public AnotherObject(int value){
  this.a=value;
 }
 
}

How does JVM create Heap?
When we invoke main method of java class, the first thing JVM does is to acquire default or configured size memory from underlying Operating system in order to run our program in a given memory. (In part 2 discuss details about configurations etc…)
Lifecycle:
Life cycle of an object entirely depends upon the “scope” or “visibility” of its reference variable and reference variable could be declared as “local variable” Or “instance variable”.

Local variables are alive as long as the method is on the stack.
Instance variables are alive as long enclosing instance on heap has valid reference to it.

Object Destruction (Garbage Collection):
Once objects are created on heap, they occupies some memory.Those objects are considered LIVE on heap as long as they have valid reference referring to them. As soon as reference goes away, object is considered as an orphan and can be safely removed from memory by the Garbage Collection. Sometimes,having too many objects doing nothing (due to some bug in code) can occupy whole memory and lead to OutOfMemory issue. (how to troubleshoot OOM issue is covered in Part 3 of this serires).

Lets look into the example below and its pictorial representation to see logical view on heap.

public class GarbageCollectionExample {

 public static void main(String[] args) {
  //create instance of KeyValuePair , assign key="Rajesh", value="Khullar"
  KeyValuePair kvp1=new KeyValuePair("Rajesh","Khullar");// Execution 1
  
  //create another instance of KeyValuePair , assign key="Test", value="Me"
  KeyValuePair kvp2=new KeyValuePair("Test","Me");// Execution 2
  
  // assign reference of kvp1 to kvp3. 
  KeyValuePair kvp3=kvp1;// Execution 3
  
  //make it GC candidate
  kvp1=null;// Execution 4
  
  //at this point, still 2 live objects on heap which has valid references
  
  //now mark it null and hand over to GC.
  kvp3=null;// Execution 5
  
  //at this point, only 1 live object with valid reference on heap
  
    
 }
 
}

class KeyValuePair{
 private String key;
 private String value;
 
 public KeyValuePair(String key,String value){
  this.key=key;
  this.value=value;
 }
 
 public String getKeyValue(){
  return this.key+" : "+this.value;
 }
}



More in Part 2, Stay Tuned.

No comments:

Post a Comment