Author Archive: omerhub

JVM Architecture at your tips!

Hola people,

Have you ever wondered how are your java files executed or where is your local variables or class data stored or how does JVM works? If yes, and you still confused about all of it, then this post is what you must read.

In this post, we will be discussion JVM Architecture in detail.

INTRODUCTION

Before we start with the JVM architecture, let us revise the compiling and linking of our C code. Lets just brief ourselves to how C codes are compiled and executed and then we’ll go through the overview of Java code compilation and then into the main architecture.

C/C++ CODE

Let us suppose there are 3 classes: a1.c (with main function), a2.c (with f1 function) and a3.c (with f2 function). These classes are then sent to the compiler which then generates machine code for these 3 classes. (a1.obj, a2.obj and a3.obj). The machine code is then sent to the linker to generate an executable code i.e a.exe file. This a.exe file is then sent for execution in RAM. Hence. execution process in C/C++ is quite fast.cprogrambasic001

JAVA CODE

Let us suppose there are 3 java source files: a1.java (with main method), a2.java (with f1 method) and a3.c (with f2 method). These classes are then sent to the compiler which then generates byte code i.e the class files. (a1.class, a2.class and a3.class). The byte code is then sent to the JVM which resides in RAM. (Remember, there is no linking done in Java). The JVM the loads the class files (with the help of class loaders) from respective class paths and then verifies bytecodes for any viruses, etc (Java codes are always secure). The after verifying the byte code, the execution engine executes the byte code and produces machine code. Hence. the process is quite slow compared to C language.

JAVA VIRTUAL MACHINE (JVM)

JVM is a virtual machine that resides in our memory and is responsible to translate bytecode to machine code or into actions or Operating System calls. For example, a request to establish a socket connection to a remote machine will involve an Operating System call. Different Operating Systems handle sockets in different ways – but the programmer doesn’t need to worry about such details. It is the responsibility of the JVM to handle these translations so that the Operating System and the CPU architecture on which the Java software is running is completely irrelevant to the developer. (See figure below.)

java-program-executionBASIC PARTS

JVM consists of 3 components:

1. ClassLoader SubSystem: This system is responsible for loading, linking and initialization of our class files.

  • Loading: Have you ever wondered while using any java class like String, or Object from where do they get imbibed in your project? They must be residing at some place in your system and if they do, they must be loaded before your class_loader_hierarchyapplication does. This loading of all your JAVA API classes path ( the runtime classes in rt.jar, internationalization classes in i18n.jar, and others.)  is done by BOOTSTRAP CLASSLOADER. Then the classes in JAR files in the lib/ext directory of the JRE,etc are loaded by EXTENSION CLASSLOADER. And in the later stage all user-defined classes gets loaded as and when required by SYSTEM CLASS LOADER. So there are basically 3 classloaders: Bootstrap Loader, Extension and System Class Loaders.
  • Linking: The bytecode is verified (all bytecode is verified  for any virus,etc) , prepared (i.e all static variables are initialised to default values) and resolved (all memory symbolic references are replaced with original references from method area) during this process.
  • Initialization: In this phase the static classes are executed and static variables are given their original values.

2. RunTime Memory Areas: As we know, to load any class or to store any variable, constant,etc some memory is required. Also. to execute some memory is again required. This memory is fetched from specially designated Runtime memory areas residing in JVM. JVM consists of 5 runtime data areas.

  • METHOD AREA: It consists of all the class data (static variables, method implementations, etc)
  • HEAP AREA: it consists of the object data.

Both the above areas are not thread-safe i.e all the thread access the same data here. The following are thread-safe areas, i.e one per each thread.fig5-3

  • STACK AREA: For each thread in the stack, a separate memory (TLA) will be allocated. Each entry in the stack is known as a stack frame which consists of 3 parts: local variable, frame data and operands.
  • PC Registers AREA: These hold the next executing instruction for each thread present in stack.
  • NATIVE METHOD STACK AREA: This holds the stack area for native emthods in our code.

3. Execution Engine: This is the central part of the JVM architecture which is responsible to translate your bytecode into machine code i.e your operating system could read and execute. It consists of 4 parts:

  • INTERPRETER: Interpreter does the line by line interpretation of our bytecode.
  • JIT COMPILER: Interpreting the loop code line-by-line can consume a lot of time. The Just-In-Time Compiler comes as a saviour. It compiles the bytecode and generates the machine code at once. It first converts the hotspot code into the intermediate code with the help of intermediate code generator. The Code optimizer then optimizes the intermediate code which is the converted into the native or machine code by target code generator.
  • PROFILER: How do we know, whether the code consists of loops, or recursion is taking place during interpretation of our bytecode? This is done by Profiler. Profiler identifies the hotspots in our bytecode and send them to the JIT compiler.
  • GARBAGE COLLECTOR: It is responsible to remove unused objects present in heap area to allow new object allocations. This process of allocating allocating new objects and removing unused objects to make space for those new object allocations is known as Memory Management. We will discuss it in detail in next post.

jvm-architecture

Sometimes, we require native codes or libraries in our application. These native information is provided by the JNI (Java Native Interfaces) stored in the Native method libraries. The whole JVM Architecture is now explained in the diagram below:

JvmSpec7

SUMMARY

The Java Virtual Machine exists only in the memory of our computer. Reproducing a machine within our computer’s memory requires a mechanism which is the byte code instruction set.

To examine byte code, we can use the Java class file disassembler, javap. By examining bytecode instructions in detail, we gain valuable insight into the inner workings of the Java Virtual Machine and Java itself. Each byte code instruction performs a specific function of extremely limited scope, such as pushing an object onto the stack or popping an object off the stack. Combinations of these basic functions represent the complex high-level tasks defined as statements in the Java programming language. As amazing as it seems, sometimes dozens of byte code instructions are used to carry out the operation specified by a single Java statement. When we use these byte code instructions with the the Virtual Machine, Java gains its platform independence and becomes the most powerful and versatile programming language in the world.

jvm-jre-jdk1

Advertisements

A BEGINNER’S GUIDE TO DEPENDENCY INJECTION!!

Heya people.!

In my last post I discussed about Singletons, its advantages and disadvantages, why it is considered an anti-pattern and stated DI as a better option.In this blog, I will be proving my statement along with going through DI basics and its key benefits.

But, to start with our discussion, we first need to understand the importance of DI.

For example, if we want to make tea for our guests. We will need to collect all the ingredients such as tea leaves, water, kettle , sugar and milk all by ourselves and then put the kettle on the gas to boil water, add tea leaves, milk and sugar and let the mixture boil before we serve it. For all this time, our guests will be waiting for us to get free and meet them. Will it then not be better to have a helping hand who knows better than us to make tea, who will make tea and serve us. If the latter solution excites you, then ladies and gentlemen, welcome to the world of DEPENDENCY INJECTION!

In the above example, if we take tea as an object, then DI help us in initializing the tea object and provide the object with all the necessary resources (i.e in our case ingredients). So basically, DI provides us with what an object needs to get initialized.

Dependency Injection is all about following 3 topics:

  1. Dependency Inversion Principle (DIP)]
  2. Inversion of Control (IOC)
  3. Dependency Injection

DEPENDENCY INVERSION PRINCIPLE

It is a software design pattern that states 2 principles:

  • High-level modules should not depend on low-level modules. They both should depend on abstractions.
  • Abstractions should not depend on details. Instead details should depend on abstractions.

To explain the above principle, let us take a very simple example.

Let us suppose, we have a watcher class that logs a message when it is notified about an event. The class will somewhat look like below:

class EventLog{
    public void log(String msg){
               //log message here
      }
 }

class Watcher{
        EventLog eventLog=null;

        public void notify(String msg){
        if(eventLog==null)
              eventLog=new EventLog();
        eventLog.log(msg);
    }
}

The example given shows no problem at first, but if looked closely violates DI principle. Let us know why!

In the above example, the high level class (Watcher class) depends on the low level class (EventLog class). Also, it depends on the concrete implementation of the low-level class, which completely violates both the principles of DIP.

Also, if at a later stage, requirement arises to extend the functionality of the watcher class i.e probably to send an email or a sms or both, to the designated person every time an event is logged, we’ll have to keep adding concrete implementations in the Watcher class. This will make the code coupled and unmanageable.

class EventLog{
      public void log(String msg){
              //log message here
          }
   }

class Email{

public void email(String msg){
     //email message here
  }
}

class Watcher{

     EventLog eventLog=null;
     Email email=null;

     public void notify(String msg){
     if(eventLog==null)
             eventLog=new EventLog();
      eventLog.log(msg);

     if(email==null)
            email=new Email();
     email.email(msg);
  }
}

Hence to avoid the above situation IOC was introduced.

INVERSION OF CONTROL

It is a mechanism using which we can make the higher level modules depend on abstractions rather than concrete implementations of lower level modules.

Basically we invert the control flow of our code to conform the DIP.

So, for the above example, we make all our concrete classes (EMAIL,SMS and EventLog) implement a common interface or abstract class CommInt consisting of a method actOnNotification().


abstract class CommInt{
       public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt{
          public void log(String msg){
              //log message here
        }

     @Override
     public void actOnNotificstion(String msg) {
              log(msg);
     }
}

class Email extends CommInt{
        public void email(String msg){
              //email message here
      }

      @Override
      public void actOnNotificstion(String msg) {
            email(msg);
     }
}

class Watcher{
     CommInt commInt=null;
   
     public void notify(String msg){
       if(commInt==null)
          commInt=new EventLog();

       commInt.actOnNotificstion(msg);

       if(commInt==null)
          commInt=new Email();

        commInt.actOnNotificstion(msg);
    }
}

In the above example, although our concrete classes now depend on abstractions, still to create a concrete type and to assign it to this abstraction we, still have to create the object in our Watcher class, that takes us where we started.

Hence, our third and final topic DEPENDENCY INJECTION comes into play.

DEPENDENCY INJECTION

DI’s main motive is to reduce coupling between classes through injecting concrete implementations of a class that is using abstraction.

There are 3 ways to inject the same:

1. Constructor Injector: We pass the object of concrete class in constructor of dependent class. It is the most widely used.


public class Launcher {

 public static void main(String[] args) {
   Email email=new Email();
   Watcher watcher=new Watcher(email);
   watcher.notify("This Watcher class object sends email for its whole lifetime");

   EventLog eventLog = new EventLog();
   Watcher watcher1 = new Watcher(eventLog);
   watcher1.notify("This Watcher class object logs events for its whole lifetime");

   }
}

abstract class CommInt{
   public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt{
   public void log(String msg){
      //log message here
   }

   @Override
   public void actOnNotificstion(String msg) {
     log(msg);
   }
}

class Email extends CommInt{
   public void email(String msg){
     //email message here
   }

   @Override
   public void actOnNotificstion(String msg) {
     email(msg);
   }
}

class Watcher{
   CommInt commInt=null;
   Watcher(CommInt commInt){
     this.commInt=commInt;
   }

   public void notify(String msg){
     commInt.actOnNotificstion(msg);
   }
}

It is useful when we know the instance of the dependent class and will us the same concrete class for its lifetime.

2. Method Injector: We pass object of concrete class into the method of dependent class.


public class Launcher {

  public static void main(String[] args) {
    Email email=new Email();
    Watcher watcher=new Watcher();
    watcher.notify(email,"This Watcher class object first sends email.");
    
EventLog eventLog = new EventLog();
    watcher.notify(eventLog,"and then logs events.!");
  }
}

abstract class CommInt{
  public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt{
  public void log(String msg){
    //log message here
  } 

  @Override
  public void actOnNotificstion(String msg) {
    log(msg);
  }
}

class Email extends CommInt{
   public void email(String msg){
     //email message here
   }

    @Override
    public void actOnNotificstion(String msg) {
       email(msg);
    }
}

class Watcher{
      CommInt commInt=null;

      public void notify(CommInt commInt,String msg){
      this.commInt=commInt;
      commInt.actOnNotificstion(msg);
   }
}

It is useful when we need to pass separate concrete class on each invocation.

3. Property Injector: We pass object via a setter property that was exposed by the dependent class. It is used less frequently.


public class Launcher {

    public static void main(String[] args) {
        Email email = new Email();
        Watcher watcher = new Watcher();
        watcher.notify("This Watcher class object first sends email.");

        EventLog eventLog = new EventLog();
        watcher.set(eventLog);
        watcher.notify("and then logs events.!");

    }
}

abstract class CommInt {

    public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt {
    public void log(String msg) {
        //log message here
    }

    @Override
    public void actOnNotificstion(String msg) {
        log(msg);
    }
}

class Email extends CommInt {
    public void email(String msg) {
        //email message here
    }

    @Override
    public void actOnNotificstion(String msg) {
        email(msg);
    }
}

class Watcher {

    CommInt commInt = null;

    public CommInt get() {
        return commInt;
    }

    public void set(CommInt commInt) {
        this.commInt = commInt;
    }

    public void notify(String msg) {
        get().actOnNotificstion(msg);
    }
}

It is useful when selection of concrete and invocation of method are in different places.

All the 3 injections are best for one level of dependencies. For a chained or nested dependencies, IOC containers (like Spring, hibernate, etc) come into play. These help us to map the dependencies easily when we have chained or nested dependencies.

KEY BENEFITS

  • maintainable code
  • de-coupled code
  • extendable code
  • move dependency resolution from compile time to run time.
  • centralized configuration
  • improves application testing

In our above example of watcher class,

  • We need to change our launcher to use Email class instead of SMS or EventLog class.
  • Independent unit cases can be created to test all the concrete classes with our Watcher class.

DRAWBACK

The main drawback of dependency injection is that using many instances together can become a very difficult if there are too many instances and many dependencies that need to be resolved.

DI better than Singletons

Singletons maintain a global state which is hard to test. Also, they cannot be extended i.e you can’t change the implementation used by one class without changing it for all of them. For the said reasons, DI will always be a better option! 😀

Hope, the basic concept regarding DI must’ve been cleared. !! For any queries, leave a comment.! 🙂

Understand Singletons at one go!

If you are looking for a switch and have 0-2 years experience in Java, then this is one topic that you must know. In this post, I try to explain all aspects of the topic and in the end include all possible questions asked.

Singleton Design Pattern is the most simple but most controversial pattern in terms of complexity of usage. It was basically introduced to solve the problem of allowing only one object to control some resource, and allowing only one copy of the object to exist i.e it provides global point of access to the object. Commonly used in logging, caches, thread pools, configuration settings, device driver objects, etc.

Singleton class control object creation, limiting the number to one but allowing the flexibility to create more objects if the situation changes.

STRUCTURE

Singleton Class Diagram

  • Static member : This contains the instance of the singleton class.
  • Private constructor : This will prevent anybody else to instantiate the Singleton class.
  • Static public method : This provides the global point of access to the Singleton object and returns the instance to the client calling class.

USAGE

Singletons must be used when only a single instance of object is required in memory for a single point of access. For example

  • Accessing application specific properties through a singleton object, which reads them for the first time from a properties file and subsequent accesses are returned from in-memory objects.
  • Creating a session factory. We need one session factory per database and use the same throughout our application. Singleton objects can be used for the same.

EXAMPLES in JDK

  • java.lang.Runtime class (getRuntime() method is used to return instance)
  • java.awt.Desktop class (getDesktop() method is used to return instance)

IMPLEMENTATION (advantages and disadvantages)

Singleton class can be implemented in following ways:

1. Early Initialization (static factory method): In this implementation, singleton gets instantiated at the time of class loading. The object is referenced by a static final field which gets returned each time singleton’s getInstance() method is called.

public class SingletonClass{
           private static final instance=new SingletonClass();
           public static SingletonClass getInstance(){
                                      return instance;
           }
 }

Advantages:

  • Instance cannot be redefined due to usage of final. (ensuring one and only one instance exists)
  • No use of expensive locking or synchronization as all threads see same instance. 

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.

2. Lazy Initialization : In this implementation, the object of class gets constructed only when class is called.

public class SingletonClass{
          private static instance;
          public static SingletonClass getInstance(){
                    if(instance==null)
                           instance=new SingletonClass();
                                           return instance;
                 }
  }

Advantages:

  • Instance not constructed until class is used.

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.
  • Unsynchronized i.e if two threads access the same method at same time, they both can create two different objects of the class.

3. Double checked locking : In this implementation, when two threads enter the getInstance() method at the same time, only one thread enters the synchronization block and constructs the instance. The other thread when allowed to enter the critical sections gets the instance and returns the same instance that the previous thread created, hence allowing only one instance per application.

public class SingletonClass{
     private static instance;
           public static SingletonClass getInstance(){
                   if(instance==null){
                synchronized(instance){
                      if(instance==null) 
                           instance=new SingletonClass();
                     }
                           }
         return instance;
          }
}

Advantages:

  • Instance not constructed until class is used.
  • Synchronized upto an extent

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.
  • Static variables are initialized by JVM to default values if not explicitly initialized. Hence, threads can return the default values, when some thread is inside the critical section and busy constructing the singleton object.

4. Using volatile variable: Volatile variables are thread-safe, and changes by one thread are visible to others.Hence, in this implementation, the instance if changed, will be visible to all threads.

public class SingletonClass
{
      private static volatile SingletonClass instance;
      public static SingletonClass getInstance()
      {
            if( instance == null) 
                        instance = new SingletonClass();
            return instance;
      }
 }

Advantages:

  • OOP properities like inheritance can easily be applied.
  • Thread-safe

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.

5. Using ENUMS: Singleton implementation using enums were introduced in JAVA 5. Enums are thread-safe and serializable. The properties are guaranteed by JVM itself. Hence, is the most efficient and easiest way to construct Singleton. One can easily access it by MySingleton.INSTANCE.

public enum MySingleton {
  INSTANCE;   
}

Since Singleton Pattern is about having a private constructor and calling some method to control the instantiations (like some getInstance), in Enums we already have an implicit private constructor. And the enum declaration actually compiles to something like

public final class MySingleton {
          public final static MySingleton INSTANCE = new MySingleton(); 
}

When the code first accesses INSTANCE, the class MySingleton will be loaded and initialized by the JVM. This process initializes the static field above once (lazily).

Advantages:

  • Reflection: It has the ability to access private members of any class. Hence, to avoid relection accessing our private constructor, we could either throw an Exception inside the constructor or use ENUM and let JVM handle it itself.
  • Serialiazation: readObject() of serialization always return a new instance of the class to be serialized. Although, we can override the readResolve() method of Serialization and return the same instance, still letting ENUM handle it becomes a better option.
  • Cloning: Multiple instances can be created through cloning. To prevent the another instance to be created of the singleton instance we can throw exception from inside the clone() method. Though enums cannot be cloned.

Disadvantage:

  • Cannot be extended as enums they final.

WHY NOT JUST MAKE THE OBJECT STATIC INSTEAD OF MAKING THE CLASS SINGLETON?

If we go through semantic point of view, to make user understand that only one instance per application exists, making the class Singleton would be the best option. Also, no new object will be created referring to same instance, that later needs to be garbage collected i.e if a class whose object is made static is heavy, then every time new MyClass() gets called, an object gets created occupying memory heap space unnecessary.

SINGLETONS v/s STATIC CLASS

This is a question asked when interviewer wants to know your deep knowledge about singletons. The question asked by him, would be like when static classes can also provide one instance and can be used without creating an object, why do we need Singletons?

When to use Singletons over Static classes:

  • Capable of providing different implementations, but guarantees only one instance per JVM. e.g getRuntime() method of java.lang.Runtime class returns different implementation on different JVM but guarantees one instance per JVM.
  • can be extended and implement interfaces.
  • Can be cloned, serialized, extended and lazily loaded.
  • Easier to test

 When to use Static classes over Singleton:

Classes that provides only static methods are called Static classes. e.g java.lang.Math

  • Faster than Singletons, as methods are bonded at compile time.
  • Due to inadequate synchronization, can lead to subtle race conditions when need to maintain state.
  • Always eagerly loaded.

SINGLETONS: ANTI PATTERN

Singletons are often badly implemented and hard to unit test. The memory allocated to them can’t be freed and excessive usage can lead us to Procedural programming (as with private constructor, there is no need to extend them!). Also, scope for which the instance is unique is hard to find. Because of these disadvantages of Singletons, they are considered to be anti-pattern.

Separate JREs are expected to use separate singleton instances as they can have multiple class-loaders. Global state increases coupling in our code and makes it hard to re-factor. Also, singleton implementation cannot be changed without changing it for all the classes accessing it.

Hence, singletons are avoided by many developers and instead Dependency Injection is recommended. (to be discussed in my next post)

A class which is used (almost) universally, but does not contain state relevant to your application, can safely be implemented as Singleton.

Hope you guys liked my post. Please feel free to ask any questions related to the topic in the comments below. 🙂

Hello World!

blogforlife

Heya people,

blogforlife is all about my travel experiences, nail arts that I do, articles about the work I do, java and dance.!!

Hope you like my posts….

Happy reading!