Showing posts with label JVM. Show all posts
Showing posts with label JVM. Show all posts

Saturday, July 20, 2019

Thoughts on GC friendly programmig

Garbage Collections in Java gets triggered automatically to reclaim some of the occupied memory by freeing up objects. Hotspot VM divides the Heap into different memory segments to optimize the garbage collection cycle. It mainly separates objects into two segments - young generation and old generation.

Objects get initially created into young gen. Young gen is quite small and thus minor garbage collection runs on it. If objects survive the minor GC; then they get moved to the old gen. So it's better to use short-lived and immutable objects than long-lived mutable objects.

Minor GC is quite fast (as its runs on smaller memory segment) and hence it's less disruptive. The ideal scenario will be that GC never compacts old gen. So if full GC can be avoided you will achieve the best performance.

So a lot depends on how you have configured your heap memory and another important factor is do you code keeping in mind these aspects.

http://www.ibm.com/developerworks/library/j-leaks/
http://stackoverflow.com/questions/6470651/creating-a-memory-leak-with-java/6471947#6471947

Monday, July 20, 2015

What is Java EE container

For Java SE (or J2SE) applications JVM provides runtime environment, but the moment you switch to Java EE (or earlier known J2EE), runtime environment is provided by web or application servers.

JVM executes/runs Java applications and also provides some of the runtime services like lifecycle management for objects and API support etc. Life is not so rosy in the distributed environment and that's why we have servers for specific jobs. These servers basically fall into two categories, application servers like JBoss(Wildfly) and Glassfish and web servers like Tomcat and Jetty. These servers are also referred to as containers (in a more technical sense). So what are containers?

Java EE Container

Java EE containers are runtime environments for Java Enterprise Edition applications. As containers are implemented on top of JVM, they provide all services provided by JVM (to Java SE applications) and along with that they also provide services specific to the distributed environment. Java EE containers refer to two different types of containers known as Web/Servlet container and EJB container. They are classified in terms of what technologies they support. Let's go through both these containers in more detail:

Web Container:
Web containers run web applications which use Servlet, JSP and JSF pages and respond to HTTP calls from HTTP clients like browsers, mobile devices or other Java (SE or EE) applications. It can also host RESTful and SOAP web services. Now a subset of EJB 3.1 (added in Java EE 6), known as EJB lite can also be deployed in web containers (in fact EJB lite can also run on JVM). So, it intercepts HTTP(S) request from the client and then identifies, instantiates, initializes appropriate servlet/service endpoint; and then returns back the appropriate HTML page or response in JSON/XML/Text format. 

EJB Container:
EJB containers run enterprise applications made up of Enterprise Java Beans within the Application server. It abstracts business logic of your Java EE application and usually takes request from Servlets,  web services,  queue or other application servers. And just like servlet containers, EJB containers manages lifecycle of EJBs and provides services like transaction management, security, concurrency, naming services or ability to be invoked asynchronously.

Please note that Java EE compliant application servers support Servlet containers along with EJB containers; you can run full stack Java Enterprise Edition application. I have come across situations where people (loosely) refer to Applications servers as EJB containers. 
In the application server, web container and EJB container both share the same JVM instance. 

---

happy learning !!!

Sunday, November 16, 2014

How Garbage Collection works in JVM

Java runtime environment abstracts memory management (allocation and deallocation for object in the heap) on behalf of programmers. This allows programmers to focus more on the real work and let Java Virtual Machine (JVM) manage the lifecycle of objects. Garbage Collector is given the job of reclaiming (or collecting) memory from the objects which are no longer referenced (i.e. it frees memory from the objects which are no longer in use).

This post, I will briefly cover the overview of GC cycle and it's implication on the running application.

GC overview

When GC kicks in, it starts from the Root object and visits all the live objects. Objects which are reachable through this chain are active objects so the remaining objects are candidates for getting garbage collected. Reference counting collector and tracing collector are few popular types of GC  algorithms.

GC has below two mandates:
  1. Free up unreferenced memory so that apps allocation request for new objects can be honored without running out of memory
  2. Reclaim unreferenced memory with minimum impact to the performance (i.e. latency, throughput) of running app
If JVM doesn't run GC cycle enough, the app will run out of memory. And if it runs GC cycle too frequently, the app will loose on throughput and response time.

In short, GC is a double-edged sword.

 

What enables GC cycle

Predicting exact time of GC is incredibly difficult. JVM specification doesn't guarantee any behavior and hence all vendors are free to implement it in their own custom way. Specification just says, that, if an object needs to get allocated memory and there is not enough free memory in the heap for allocation then application should throw OutOfMemory error. I have listed below few pointers on what leads to GC:

Steps which lead to GC:
  1. Memory allocating thread doesn't find large enough consecutive memory for the object it wants to allocate
  2. JVM thread notifies to the GC of above problem
  3. GC determines if it's safe to start a GC cycle
  4. It is safe to start GC when all active application threads are at safe points(i.e. GC cycle will not cause any issue to running application)
  5. GC kicks in
Be careful that the decision making algorithm is not so trivial as discussed above, but it gives fair idea of what may lead to a GC cycle. As a programmer/administrator you can't do much (unless you use your own custom GC library). But, Java gives few technique which can be used to request GC.
Within the application (or code):
You can call below method(s) to request full garbage collection cycle.
     System.gc() or 
     Runtime.getRuntime.gc()

Out of application: 
You can request GC cycle though jconsole as shown below (jconsole provides a button to request GC)


Both approaches are one and the same. It suggests/request that, GC should try recycling unused objects in order to free the memory they currently occupy. This is just a hint or request to GC; GC has all rights to ignore the request.

References:
http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140228.html

Related Articles

Tuesday, December 31, 2013

Java Bytecode or class file

This post, I will be focusing on the content of Java's class file, known as bytecodes.  Java Virtual Machine uses the stream of bytecode from the class file for executing the program. As a Java programmer one doesn't need to bother about internal structure and format of bytecodes at all, but it's worth knowing how it is organized under the hood.  

Reading Bytecodes

Before reading bytecodes, let's generate one first. I am taking a simple HelloWorld example for this. 

public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello, World!");
}
}

Save above class in your editor to compile it (or compile manually through command prompt). Locate the generated class file and open the same in the text editor. Shown in the below screenshot :


Some of the text does look familiar but it doesn't make sense at all. In fact, it doesn't look like bytecode of the HelloWorld.java. It will make more sense if it had numbers( binary/hex). Even if you use the FileReader API of java to read the class file; the result will be the same. You will neither see the stream of bytes nor code mnemonics. 

Are we missing something ? Yes.
Class file consists of stream of bytecodes. So we need to read the file as an array of the byte as shown in below class.


import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import javax.xml.bind.DatatypeConverter;

/**
 * Utility to read the contents of class file as byte stream
 * 
 * @author Siddheshwar
 * 
 */
public class ReadClassAsByteStream {

 public static byte[] readFileAsByteArray(String fle) throws IOException {
  RandomAccessFile f = new RandomAccessFile(new File(fle), "r");

  try {
   int length = (int) f.length();
   byte[] data = new byte[length];
   f.readFully(data);
   return data;
  } finally {
   f.close();
  }
 }

 // test method
 public static void main(String[] args) throws IOException {
  String file = "D://workspace/JavaSample/src/HelloWorld.class";
  byte[] b = null;

  try {
   b = readFileAsByteArray(file);
   // convert byte array to Hex
   System.out.println(DatatypeConverter.printHexBinary(b));
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

Output:
CAFEBABE00000033001D0A0006000F09001000110800120A001300140700150700160100063C696E69743E010003282956010004436F646501000F4C696E654E756D6265725461626C650100046D61696E010016285B4C6A6176612F6C616E672F537472696E673B295601000A536F7572636546696C6501000F48656C6C6F576F726C642E6A6176610C000700080700170C0018001901000C48656C6C6F20576F726C642107001A0C001B001C01000A48656C6C6F576F726C640100106A6176612F6C616E672F4F626A6563740100106A6176612F6C616E672F53797374656D0100036F75740100154C6A6176612F696F2F5072696E7453747265616D3B0100136A6176612F696F2F5072696E7453747265616D0100077072696E746C6E010015284C6A6176612F6C616E672F537472696E673B2956002100050006000000000002000100070008000100090000001D00010001000000052AB70001B100000001000A000000060001000000010009000B000C00010009000000250002000100000009B200021203B60004B100000001000A0000000A000200000003000800040001000D00000002000E

Bingo !!! Now, this looks like what we were looking for.
In the main method, I have used DatatypeConverter API to convert the byte array into hex format to print the content in more compact format. 

What is Bytecode

Bytecode is a series of instructions for the Java Virtual Machine and it gets stored in the method area (of JVM). Each instruction consists of a one-byte opcode followed by zero or more operands. The opcode indicates the action to be taken by JVM. The number of opcodes is quite small  (<256) and hence one byte is enough to represent opcodes. This helps to keep the size of the class file compact.

Important Observations on Generated Bytecode

  1. Java class file is a binary stream of byte. These bytes are stored sequentially in class file, without any padding between adjacent items. 
  2. The absence of padding ensures that class file is compact and hence can be quickly transferred over the network. 
  3. Items which occupy more than one byte are split into multiple consecutive bytes in big-endian style (higher bytes first ).
  4. Notice that, the first four bytes are "CAFEBABE" -known as the magic number. The magic number makes the non-Java class file easier to identify. If the class file doesn't start with this magic number then it's definitely not a Java class file. 
  5. The second four bytes of the class file contain the minor and major version numbers. 

Mnemonics Representation of Bytecode

Bytecode of HelloWorld program can be even represented as mnemonics in a typical assembly language style. Java provides class file disassember utility named as javap for doing it. javap utility provides multiple options for printing the content of class file. You can also use ASM Eclipse plugin to see disassembled bytecode of a class in Eclipse.

D:\workspace\JavaSample\src>javap -c HelloWorld.class
Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hello World!
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

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!!!

Wednesday, May 1, 2013

Life Cycle of an Object in Java

In Java, objects play the pivotal role; so understanding its instantiation, and how and when it gets garbage collected is important. This post covers the life cycle of objects inside Java Virtual Machine. But keep in mind that, successful creation of the object is possible only if class is already loaded in JVM (by class loader).


Object Creation 

Class instantiation activity gives life to an object and thereafter you can call its methods to manipulate states/attributes. Object creation is done by Java Virtual Machine(after class has been loaded). When JVM creates a new instance of a class, it allocates memory on the heap to hold the object's instance. Memory is allocated for all variables/attributes declared in object's class and in all its superclasses (including hidden attributes). Once the virtual machine has allocated memory for the new object, the machine initializes the instance variable to default initial values. After this VM gives proper initial value depending on how the object gets created:

   1.  new keyword
        Person p = new Person();
        String s = new String("life");
            This is one of the most frequently used approach to create an instance of a class. 

       2.  newInstance() on a Class / Reflection
            Class class = Class.forName("fully.qualified.class.name");
            Object obj = class.newInstance();
            Person p = (Person)obj;
             

       3. Cloning         
           Person pClone = (Person)p.clone(); 

           Make sure that, Person class implements Cloneable interface and also provides the definition of the clone() method. 

       4. Deserialization      
           FileInputStream fis = new FileInputStream("person.ser");
           ObjectInputStream ois = new ObjectInputStream(fis);
           Person per =(Person)ois.readObject(); 
          
           Deserialization is a technique to convert the encoded byte stream into the corresponding object as 
           shown above. Refer to the detailed tutorial.

       5. Implicit Instantiation
           All above techniques explicitly creates an object of a class. Apart from above, there are multiple implicit ways of object creation as well :
              
           1. Class loading : For every type that a JVM loads, it implicitly creates a new Class object to                  represent that type.
           2. String Literals : When JVM loads a class which has String literals (i.e. String PI = "3.14"), 
               it might create a new String object. 
           3. Expression Evaluation : Process of evaluation an expression like String concatenation
               can also create new objects. 
                   
     So above explicit/implicit object instantiation techniques give proper initial value to the object. JVM uses one of the three techniques to do this task, depending on how the object is being created.

    If the object is being created because of a clone() invocation, the virtual machine copies the values of the instance variables of the object being cloned into the new object. If the object is deserialized via a readObject() invocation on an ObjectInputStream, the virtual machine initializes non-transient instance object variables from values read from the input stream. Otherwise, the virtual machine invokes an instance initialization method on the object. The instance initialization method initializes the object's instance variables to their proper initial value. 
    The Java compiler generates at least one instance initialization method for every class it compiles. In the  Java class file, the instance initialization method is called "<init>". For each constructor in the source code of a class, the Java compiler generates one <init>() method.  

    Object in action

    Once object is created successfully, its ready for the real action.
    obj.haveFun();

    Garbage Collection of Object / End of life

    Application can allocate memory for object via explicit and implicit ways described under object creation, but they can not explicitly free that memory. To signal to JVM that an object is ready for garbage collection, object needs to get unrefrenced in either of below ways :

    1. Explicit unreferencing
        person = null;  //person is an instance of Person   

    2. Object goes out of scope
        An Object created inside a method goes out of scope once method returns to the calling method.
        So in below case once method() is over, p implicitly becomes null. 

        public void method(){
           Person p = new Person();
           //method action
        } 

       After unrefrencing, VM can reclaim that memory. Virtual machine can decide when to garbage collect unrefrenced object. But specification doesn't guarantee any predictable behavior. It is up-to the VM to decide when to reclaim memory from unrefrenced object or it might NOT reclaim memory at all.
    If the class declares a finalizer (i.e. public void finalize() method ) then Garbage Collector will execute the finalize() method on the instance of the class before it frees the memory space occupied by that instance. So clearly, exact time of garbage collection is unpredictable.


    Friday, March 22, 2013

    JVM Architecture

    Java Virtual Machine (JVM) runs/executes java's compiled file(.class). Its job is to load class files and then execute the bytecode contained inside it. Below diagram shows the life cycle of a java program.
    More details about bytecode on this post.


    Java Virtual Machine is called virtual because it is an abstract computer (or machine) defined by specification. The implementation of the specification is also known as JVM. JVM in general could mean specification, implementation or instance. Let's cover these aspects in detail:

    JVM Specification: [link]
    JVM specification is template for implementing JVM tool. Specification defines certain features every JVM must have but leaves many choices to the designer of each implementation. It's the specification which says, how your JVM should behave? Like, if JVM runs out of memory, it should throw out an appropriate error. Also, JVM specification is different from the Java specification (Java specification controls the language; JVM specification controls the tool which executes programs)

    JVM implementation
    Specification is an abstract thing; it gets converted into a product after implementation. When you install JVM in your computer/laptop, we refer to a particular JVM implementation: Windows JVM for 32 bit machine, windows JVM for 64 bit machine, JVM for Mac OSX etc . JVM specification is flexible enough to allow implementation to be either completely in software or to a varying degree in hardware .

    JVM instance
    This is one of the most confusing aspect. JVM instance comes into picture when you run your Java application. Runtime instance job is, to run a Java application( i.e. java className). So when application gets launched runtime instance gets life and when application completes, the instance dies. Your application could be as small as a class which just prints "Hello World" or it could be as complicated as a distributed application (.war or .ear) which runs 24/7, until the world stops. So, if you start 3 applications at the same time using same JVM (implementation); it means that you have 3 JVM instances. Each Java application runs inside its own JVM.

    Each Java application runs inside a run-time instance of some concrete implementation of the abstract specification of the JVM.

    Architecture

    JVM consists of two major subsystems and memory areas defined in specification. 
    source : artima.com

    Class Loader Subsystem
    This subsystem, loads class files from both the program and Java API. As per specification, only those files which are needed are loaded. It loads types (classes and interfaces) using fully qualified name. After loading, it parses information about type( from the binary data contained in the class file), and then places this type information into the method area. And as the program runs, JVM places all the created objects on the heap.
    This post talks class loading and unloading in detail.

    Execution Engine Subsystem
    Execution engine executes bytecode instructions contained in the loaded classes. This component of JVM can have some aspect implemented as hardware. JVM can support multiple execution techniques:

     1. bytecode interpreter : Interprets the byte code, one at a time.
     2. just-in-time compiler: faster than interpreter but  requires more memory.  Bytecodes of the method
     are compiled to native machine code when method is invoked for the first time. Also machine code      
         is cached so that it can be reused on the subsequent calls.
     3. adaptive optimizer: In this technique, JVM starts by interpreting the bytecodes but monitors the
         activity of the running program and identifies the most heavily used areas of code. As program
         runs, the virtual machine compiles to native machine code and optimizes only those heavily used
         areas of code. The rest of the bytecode is interpreted.

    Runtime Data Areas
    When a program runs, JVM organizes the memory it needs to execute a program into several runtime  data areas. Specification of data area is quite abstract to let it get implemented on a wide variety of computers and devices. Each instance of the JVM has one method area and one heap. These areas are shared by all threads running inside the virtual machine. Each running thread has its own PC (program counter) register and Java Stack. If thread is executing a Java  method (not a native method), the value of the PC register tells the next instruction to execute. Java stack stores the state of Java method invocation(not native invocation) for the thread. The state of a Java method invocation includes its local variables, the parameters with which it was invoked, its return value (if any), and intermediate calculations. The state of native method invocation is stored in an implementation dependent way in native method stacks, as well as in registers or other implementation dependent memory areas. 

    Reference:
    http://www.artima.com/insidejvm/ed2/jvm5.html 
    http://www.artima.com/insidejvm/ed2/jvmP.html
    http://kkarthikeyanblog.wordpress.com/2012/08/23/helloworld-in-jvms-view-how-java-program-executed-internally-in-jvm/ 

    Related Post : Understanding Java Bytecode  Class Loading and unloading in JVM