Showing posts with label permgen. Show all posts
Showing posts with label permgen. Show all posts

Saturday, May 4, 2013

Class Loading and Unloading in JVM

Class Loader is one of the major component (sub system) of the Java Virtual Machine(JVM). This posts talks about loading and unloading of a class (or interface) into virtual machine. JVM specification refers to classes and interfaces as type.

A Java program is composed of many individual class files, unlike C/C++ which has single executable file. Each of these individual class files correspond to a single Java class and it gets loaded the first time you create an object from the class or the first time you access a static component (block, field or method) of the class.

A class loader's basic objective is to service a request for a class. JVM needs a class (ofcourse for instantiating it), so it asks the class loader by passing full name of the class. And in return class loader gives back a Class object representing the class(more detail here). Below diagram shows sequence of steps:



Class Loading

In the JVM architecture tutorial (link), I have discussed class loader subsystem briefly. JVM has a flexible class loader architecture that enables a Java application to load classes in custom ways. Each JVM has at 
least two class loaders. Let's cover both of them:
  • Bootstrap class loader : Part of JVM implementation and it is used to load the Java API classes only. It "bootstraps" the JVM and is also known as primordial, system or default class loader.
  • User-defined class loaders : There could be multiple user-defined class loaders. Class loaders are like normal Java classes, so application can install user-defined class loaders to load classes in custom way. You can dynamically extend Java application at run time with the help of user-defined class loaders.
JVM keeps track of which class loader loaded a given class. Classes can only see other classes loaded by the same class loader (for security concerns). Java architecture achieves this by maintaining name-space inside a Java application. Each class loader in a running Java application has its own name-space and class inside one class loader can't access a class from another class loader unless the application explicitly permits this access. This name-space restriction means :
  • You can load only ONE class named as say Fruit in a given name-space. 
  • But you can create multiple name-space by creating multiple class loaders in the same application. So, you can load three Fruit classes in three different class loaders. And all these Fruit classes will be unaware of the presence of rest two.
Now, obvious question is, how these multiple class loaders in the same application load classes ?
Class loaders use Parent-delegation technique to load classes. Each class loader except bootstrap class loader has a parent. Class loaders asks its parent to load a particular class. This delegation continues all the way to the bootstrap class loader, which is the last class loader in the chain. If the parent class loader can load a type, the class loader returns that type. Otherwise current class loader attempts to load the class itself. This approach ensures that you can't load your own String class, because request to load a new String class will always lead to the System/bootstrap class loader which is responsible for loading Java API classes. Also classes from Java API get loaded only when there is a request for one. 

What if, I create my own class in Java.util package ?
Java gives special privileges to classes in the same package. So does it mean my class say Jerk inside Java.util package will get special access and security will get compromised ?  
Java only grants this special access to class in the same package which gets loaded by the same class loader. So your Jerk class which would have got loaded by an user-class loader will NOT get access to java.lang classes of Java API. So code found on class path by the class path class loader can't gain access to package-visible members of the Java API. 

Class Unloading

Lifetime of a class is similar to the lifetime of an object. As JVM may garbage collects the objects after they are no longer referenced by the program. Similarly virtual machine can optionally unload the classes after they are no longer referenced by the program. 

Java program can be dynamically extended at run time by loading new types through user-defined class loaders. All these loaded types occupy space in the method area. So just like normal heaps the memory footprints of method areas grows and hence types can be freed as well by unloading if they are no longer needed. If the application has no references to a given type, then the type can be unloaded or garbage collected (like heap memory).

Until Java SE 7; classes (and Constant pool) were stored in Permanent Generation (or PermGen).  Tuning PermGen size was complicated so Java SE 8 has completely removed PermGen and now classes (Java HotSpot VM representation of class) are moved into native or heap memory, link.

Types (Class/Interface) loaded through the bootstrap loader will always be reachable and will never be unloaded. Only types which are loaded by user-defined class loaders can become unreachable and hence can be unloaded by JVM. A class instance can be reachable in following case:
  • Class instance will be reachable if the application holds an explicit reference to the instance. 
  • Class instance will be reachable if there is a reachable object on the heap whose type data in the method area refers to the Class instance. 

References:
http://www.artima.com/insidejvm/ed2/jvm5.html 

Related Articles:
how-garbage-collection-works
jvm-architecture
life-cycle-of-object-in-java

---

calling it a post; do give your feedback!!!

Tuesday, February 19, 2013

static keyword in Java

Java allocates memory after instantiation a class, using new operator. But there is one exception to this rule, static keyword.

The static keyword is used with data and methods of the class:
  1. If you want to have only a single piece of storage for a particular field, regardless of how many objects of that class are created, or even if no objects are created.                                    
  2. If you need a method that isn't associated with any particular object.      
static members of the class are also referred to as class data ( and class methods) or in general class members. Class name is the preferred way to refer to static members of the class, though you can use objects as well. You can't apply static keyword to local variables.

 public class StaticDemo {  
      private static int count; // initialized to default value of int i.e. 0  
   
      public static int getCount() {  
           return count++;  
      }  
   
      public static void main(String[] args) {  
           System.out.println(" Count: " + StaticDemo.getCount());  
           StaticDemo sd = new StaticDemo();  
           System.out.println(" Count: " + sd.getCount());  
      }  
 }  
Output :
 Count: 0
 Count: 1

Note, the first call to method, getCount() is using Class name but the second call is through an instance of class. The output returned is consistent. This example proves a point that there is a single storage for static data.

It's debatable if static methods are Object Oriented as you call methods without creating objects. My suggestion, avoid using lots of static methods.

static Initialization and static block

Below 2 are one and same :
       private static int count = 10;  //static initialization

or

       private static int count;
       static{    //static block
          count=10;
       }      

And you can have multiple statements inside a static block.

Order of Execution

Below example demonstrate the order of invocation :

 public class StaticLoadDemo {  
      static {  
           System.out.println("Class StaticDemo loading...");  
      }  
   
      static final int c = 5; // static initialization  
      static int a;  
   
      static { // static block  
           a = c;  
           System.out.println("value :" + a);  
      }  
   
      StaticLoadDemo() {  
           System.out.println("Constructor");  
      }  
   
      public static void main(String[] args) {  
           new StaticLoadDemo();  
      }  
   
      static {  
           System.out.println("final static block");  
      }  
 }  
Output:
Class StaticDemo loading...
value :5
final static block
Constructor

Important Points:
  1. Static block/initialization gets invoked right after class gets loaded. The output of the above class confirms the same.
  2. Static block is called only once (during the lifetime)
  3. If StaticLoadDemo class extends a base class named as Base. Then static blocks of Base class will be invoked first,  followed by subsequent subclasses.
  4. Order of initialization is static first if they haven't been already initialized by previous object creation, and then non-static component.

Inheriting static component

static components are associated with the class and not the individual object. So if a method is static, it doesn't behave polymorphically.
 class Super {  
      public static void printHello() {  
           System.out.println(" hello --base class");  
      }  
 }  
   
 public class Derived extends Super {  
      public static void printHello() {  
           System.out.println(" hello --derived class");  
      }  
   
      public static void main(String[] args) {  
           Super s = new Derived();  
           s.printHello();  
      }  
 }  
Output:
hello--base class

Memory allocation and  de-allocation

static methods (in fact all methods), as well as static data, are stored in the PermGen section of the heap, since they are part of the reflection data (class related data, not instance related data). 
  1. static primitive variables are stored in PermGen (Permanent Generation) space.
  2. If static data references to an Object; then reference is stored on PermGen but the actual object gets stored in heap(young/old generation).
 static members get garbage collected only when class gets unloaded (details here).

---
do post your feedback !!!