Today let us understand the compiling process in java, that is, preface to java virtual machine and architecture.
So, let’s get started,
When we write a java program we use java compiler to compile and get the dot class (.class) file or bytecode as a output.
But JVM responsibility is to just load the class file and produce the output. This is a simple layman definition.
Also read – java features
Now our application consists of .class (dot class) file which is a sub-output that is generated by the java compiler.
It is loaded into first major component of the JVM which is the class loader subsystem.
The class loader subsystem is responsible for loading your bytecode and treating a bytecode as an instruction.
Now it should be loaded to perform some operations with respect to other classes which are associated with the JVM.
So for example, collection classes, system classes and all the various types of classes which are there in the class loader subsystem provided by the JVM are taken care of.
Also read – java overview
By using the class loader subsystem the class files are been loaded. But there are various certain internal processing in the class loader subsystem which are,
Loading is a phase where class files are loaded. Basically loading is of three different kind.
The first one is the bootstrap loader, the second one is application class loader and the third one is extension loader. Let’s understand one by one,
Bootstrap loader is responsible for loading your internal java class files which are there in the file called rt.jar. You often encounter the rt.jar file in your java directory which consists of all the important classes and important packages which are required by the java.
All the primary packages and all the primary classes are there in the rt.jar file.
Extension class type loader:
Extension class type loader is responsible for loading important extensible file which are needed by JVM or the classes which are required by the JVM for further processing.
It is basically in lib / hd directory. So lib / hd contain all the extension classes which are loaded after the bootstrap loader. Now after extension class is loaded successfully there is third important thing which is loaded called as classpath application.
Application class paths are specified with the cp parameter or -cp (minus cp) parameter.
You can explicitly supply this parameter command which is -cp (minus cp) or you can load these class paths in your environment variable as well.
So the loading phase is over. Now let’s get back to second phase called as linking.
Linking is the phase where most of the work is done. Now linking involves three sub process which is verifying, preparing and resolving.
Verify phase is a phase where your java bytecode is taken care of. It basically checks bytecode whether it is compatible to the JVM specification or not.
If there is a certain problem while verifying the java bytecode it will throw us a common error which is class not found exception which happens during the verifying phase.
Now the second phase is prepare phase. In the prepare phase all the class data variable or the instance variable are been initialized to their default value.
For example if I have a variable as,
public static boolean = true;
In the prepare phase the variable which is of boolean type of static will be initialized to the default value of boolean type which is false not true.
Because prepare phase involves initializing with the default value not with original value. Now after preparing phase we have the resolving phase.
Now resolve phase job is to load the other associated class which are there in the main class. For example, all the reference variables are initialized during the resolve phase.
Say, you have a class called “Bike”. Now “Bike” can consist of another class “Owner”. Now during the resolve phase the “Bike” class will go and check whether there is definition for “Owner” or not.
If there is a definition then there is no problem it will continue to resolve. But if it’s failed to find the class or the another class “Owner” it will throw an error or exception ClassNotFoundException.
After the resolve phase the third phase comes into play which is the initialization. Now initialization is a phase where static initialization part is initialized first and after that all the values which we assigned in the prepare phase.
For example, in the prepare phase we have assigned variable to false which is default value, is initialized to the actual value.
As I discussed in the prepare phase we have public static boolean initialized with false. Now in the initialization phase it will be initialized as
public static boolean = true;
which is the actual value in the initialization phase. So that’s how class loader subsystem works in a much simpler way.
There is some other component which is called as “Runtime data part” which comprises of all the memories which are going to be utilized by the JVM itself. Now let’s encounter the method part first.
Method part is an runtime data access area whose responsibility is to load your class data or the metadata which correspond to class.
All the data which is present or which correspond to the class will get stored in the method part. Basically the method part size is 64 megabyte by default but it can be tuned up by using a “comp gen command” or there is a command which I am going to discuss in the next post.
But this can be tuned up by using “xx” or “xmx” command if your server load is thousand and thousand of classes or millions of classes.
Now there maybe a probability that you will get a java.lang.OutOfMemoryError. This is due to the exceeding size of the memory utilization.
So you can tune up by using “xx”, “xmx” and using comp gen commands. When you talk about java 8, comp gen is been replaced by using meta space.
What java developer of 8 do is, they do not need any kind of external developer input to tune up the method part space.
What they did is they introduced the meta space. Now meta space is responsible for automatically allocating memory, look for expansion as well as shrinking. So that’s all about the method part.
Heap is the hardly used memory area in JVM. Heap basically stores object data. For example whenever you instantiate a new object, say
Class obj = new Class();
Now the object which is created will be there in the heap memory only.
All the properties, all the characteristics and all the attributes of the object will get stored in the heap. For example, you can store arrays. Since arrays are also objects.
So objects get stored in the heap. By default heap memory is one fourth of the physical memory.
But this can also be tuned up using “xx command”, “xs” for the small size and “xmx” for the maximum size. So this can be tuned up by using parameter command.
Java stack contain stack frame. It is basically per method invocation. The task of the java stack is to load up the method and invoke the method based on the preference or based on the last in first out preference.
Now we often call the method one by one. So for example, one thread is calling method one. Now method one is calling method two.
So method one will stack first. Then method two will come into picture and then method three will come to picture.
Now this will be popped up based on the returning occurrence and we don’t need to worry about that because they are going to return anyway.
Sometimes, java stack is stacked up again and again. What happens actually is whenever you write a program and there is a recursive algorithm that is not encountered while handling by the developer.
So there occurs stack frame added again and again. It will end up in stack overflow exception.
Now, this can be tuned up. I guess there is a command called “xx”, again which is used to change the size of the java stack frame.
Basically you don’t need to worry because it will be cleared automatically by the jvm itself.
PC registers are basically program counter registers which basically point to the next instruction to be executed.
PC register is responsible for per thread management. Suppose there are three threads, one, two and three. Thread one counts the instruction for the thread two, thread two counts the instruction for thread three and basically it is a pointer to the next instruction to be executed.
Native Method Stack:
Native method stack works parallelly with the java stack. In java, native method stacks is basically operating system dependent.
All the operating system native operating system dependent classes are loaded into this native method stack. For example, there is a library in the “lib” folder called as dll’s.
There are lot of “dll” available if you are using windows. Now “dll” is responsible for holding your class data corresponding to the operating system dependency.
If you are using windows then there is a .dll (dot dll) file. If you are using Linux or UNIX there may be probability that you will find .sor (dot sor) kind of file extension. Now these all belong to native method stack.
Execution Engine is responsible for executing bytecode instruction. It basically comprises of various subsystem which are interpreter, garbage collection, just-in-time compiler and there is hotspot profiler.
Interpreter interprets the bytecode instruction line by line. It checks whether the bytecode instructions are compatible to execution engine or not and it passes using the native method interface and helps in the execution.
Now here comes picture of just-in-time compiler. Whenever execution engine encounter the similar kind of instruction to be executed again and again, what it does is it compiles piece of classes or some piece of code.
It compiles some part of code which is repeated over and again. So that it can improve the performance in the later time. For example, if it encounters XYZ XYZ XYZ again and again, XYZ is actually an instruction.
Now what JIT does is, JIT pre-compiles XYZ automatically. Now in the next instruction if XYZ is encountered, JVM reduces that time and thus leads to the performance improvisation.
A Hotspot profiler keeps an eye on the bytecode and it helps the JIT compiler to basically look for statistics and provide the statistic results.