From this post I thought of discussing how underlying components work together for a successful execution of a Java program. Content in this post consists of a collection of knowledge I gathered after going though several articles on this topic.
Most of us never bothered about internal stuffs related to Java, because IDEs have made our life a lot easier. But it’s worth if you have some idea about internal stuffs as if you happened to work with an enterprise level application, and faced with memory issues. In this article, I though of going from basic concepts to an intermediate level.
JVM, JRE, JDK
In brief “JVM (Java Virtual Machine) is an abstract machine. It is a specification that provides runtime environment in which java bytecode can be executed.” Which implies JVM is merely a concept. I’ll come back to JVM later to discuss more.
JRE (Java Runtime Environment) provides a runtime environment (implementation of JVM). JRE contains the concrete implementation of JVM (eg: HotSpot JVM, JRockit, IBM J9), set of libraries and other files need for JVM. Different vendors release their own JRE, based on a reference.
JDK is for developers to create Java program. JDK consists of JRE + development tools such as ‘javac’.
One important thing to remember is all JVM, JRE and JDK are platform-dependent.
JVM in Detail
It is said that JVM is;
- A specification where working of Java Virtual Machine is specified. But implementation provider is independent to choose the algorithm. Its implementation has been provided by Sun and other companies.
- An implementation Its implementation is known as JRE (Java Runtime Environment).
- Runtime Instance Whenever you run a java program, an instance of JVM is created.
JVM is responsible for following operations:
- Loads code
- Verifies code
- Executes code
- Provides runtime environment
Internal Architecture of JVM
- Classloader : Classloader is used to load class files. The embedded classloader in JVM is also called “primordial class loader”. Depending on the class name, classloader can search for the .class file in directory structure. User can also define classloaders (called “non-primordial class loader”) if required.
- Method (Class) Area : Also called non-heap area, it has 2 subsections. “Permanent Generation – This area stores class related data from class definitions, structures, methods, field, method (data and code) and constants. Can be regulated using -XX:PermSize and -XX:MaxPermSize. It can cause java.lang.OutOfMemoryError: PermGen space if it runs out if space”. OutOfMemoryError happens when class definitions are accumulated. The other section, Code Cache is used by JIT to store compiled code (hardware specific native code).
- Heap : Area allocated for runtime data. This area is shared by all threads. We can use -Xms and -Xmx JVM options to tune the heap size. In most of the time “java.lang.OutOfMemoryError” error occurs because heap is getting exhausted. Heap consists of 3 sub-areas:
- Eden (Young) – “New object or the ones with short life expectancy exist in this area and it is regulated using the -XX:NewSize and -XX:MaxNewSize parameters. GC (garbage collector) minor sweeps this space”
- Survivor – “The objects which are still being referenced manage to survive garbage collection in the Eden space end up in this area. This is regulated via the -XX:SurvivorRatio JVM option”
- Old (Tenured) – “This is for objects which survive long garbage collections in both the Eden and Survivor space (due to long-time references of course). A special garbage collector takes care of this space. Object de-alloaction in the tenured space is taken care of by GC major”
Analysis on “java.lang.OutOfMemoryError” can be done by taking a heap-dump when the incident occours. You can refer a case-study on analyzing for a real-world case at here: http://javaeesupportpatterns.blogspot.com/2011/11/hprof-memory-leak-analysis-tutorial.html
- Stack : This area is specific to a thread. Each thread has it’s stack which is used to store local variables and regulates method invocation, partial result and return values. This space can be tuned with -Xss JVM option.
- Program Counter Register : It contains the address of the Java virtual machine instruction currently being executed.
- Native Stack : Used for non-Java code, per thread allocation
- Execution Engine : This contains 3 parts;
- A virtual processor
- Interpreter, which reads the bytecode and execute the instructions
- 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.”
In this post I want to gather a colllection of knowledge I found related to JVM from various articles. All those areticles are mentioned in Reference section below. I would like to thank all those original authors, and hope you will get some knowledge out of this as well.
- JVM internals tutorial – http://www.javatpoint.com/internal-details-of-jvm
- About JVM Memory – https://abhirockzz.wordpress.com/2014/09/06/jvm-permgen-where-art-thou/
- Understanding Java PermGen – http://www.integratingstuff.com/2011/07/24/understanding-and-avoiding-the-java-permgen-space-error/
- Java HotSpot VM Options – http://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html
- Java Classloaders – http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html
- Heap Dump Analysis with VisualVM – http://www.javaworld.com/article/2072864/heap-dump-and-analysis-with-visualvm.html
- Real-world Example for Heap Dump Analysis with MAT – http://javaeesupportpatterns.blogspot.com/2011/11/hprof-memory-leak-analysis-tutorial.html