In my opinion, Java isan amazing programming language which performs many behind-the-scene tasksautomatically, letting the user focus only on the application logic.
Java Virtual Machine(JVM), the cornerstone of Java Platform, is responsible for handling most ofthe operations which are necessary for uninterrupted execution of a Javaapplication. In this article, we will discuss five such interesting operationsthat JVM carries out surreptitiously. Though most of the Java developers areaware about the final results of these processes, many are unfamiliar with theunderlying process or functional components that are involved.
1. Class Loading
Have you ever wonderedhow the JVM finds all the necessary classes required to run your Javaapplication properly?
To run any Javaapplication, Java Runtime Environment (JRE) has to load necessary classes fromdifferent resources in to Java Virtual Machine (JVM). For this, JRE has ClassLoaders which does this dynamically based on several principles.
Not all classes are loaded by asingle Class Loader.
There are 3 built-inclass loaders in Java.
1. BootstrapClass Loader
Loads Java base classes withinJava.* packages. Usually loads rt.jar from JRE library directory.
2. ExtensionClass Loader
Loads Java extension classes.Usually loads jar files from JRE ext directory.
3.Application (System) Class Loader
Loads classes from applicationclasspath.
Not all classes are loaded in tomemory at the same time.
A class will be loadeddynamically into the JVM when it is referenced by a class that is alreadyrunning in the JVM. Java uses DelegationModel for loading classes.
In the delegation model,when a Load Request arises, that request will be delegated step by step, frombottom to top-most loader. Then the searching will start from the top-mostclass loader and if class is not found on that level, the search will step downto the next loader and so on.
We can write our own customClass Loaders
Java allows us to writeour own custom Class Loaders, but in general, we don’t have to, unless we areworking on a complex application that needs modularisation of system load orreload classes at runtime etc.
Java class loader delegation hierarchy
2. Class Initialisation
When a particular classis loaded into the JVM, all the class variables (static member variables) willbe assigned default values of their type. This is because compilerassigns default values to all the member variables of a class in the compiletime.
Additionally, a runtimeprocess of class initialisation will be performed by the JVM for any classwhich is loaded into the memory by a Class Loader.
JVM will run classinitialization only once for a loaded class
JVM will not run theclass initialisation process immediately after the class loading. However, itwill happen immediately before the first occurrence of any of the followings.
1. Creation of an objectfrom that class
2. Calling a static method or using/changing a staticvariable
3. Execution of an assert statement which is nestedwithin a top-level class
Class initialisation does thefollowings
We can initialise staticvariable in a class by defining declaration values. Also, some of you may havealso heard about Static Initialiser Blocks, which are used frequentlyfor initialising static variables.
Java classinitialization process involves following steps.
1. Assigndeclaration values to static variables
If a custom value declared for astatic variable, it will be assigned to that respective variable.
2. ExecuteStatic Initializer Blocks
All static initializer blocksdefined in the class will be executed.
3. Instance Initialisation
When we are creating anobject from a class, all the instance variables will be initialised to their defaultvalues. This will happen at the same time when an object is created in theheap. Additionally, another process of instance initialisation will be executedby the JVM, just before returning the reference to the created object.
JVM will run instanceinitialisation each time an instantiation takes place
Unlike classinitialisation which happens only once, the instance initialisation will happeneach time when an object is created from a class (explicitly or implicitly).
Instance initialisation does thefollowings
We can initialiseinstance variables with our custom values by defining declaration values.Additionally, just like static initialiser blocks, there are InstanceInitialiser Blocks which are also typically used for initialising instancevariables in an object.
Java instanceinitialization process involves following steps.
1. Invokesuper class constructor
Super class will be invokedexplicitly or implicitly.
2. Assigndeclaration values to instance variables
If a custom value is declaredfor an instance variable, it will be assigned to that respective variable.
3. ExecuteInstance Initialiser Blocks
All instance initializer blocksdefined in the class will be executed.
4. Executeconstructor body
Super class already invoked. Therest of the code written in the constructor will be executed.
4. Garbage Collection
We are all aware that wedon't have to worry about memory management in Java. Instead Java handles theGarbage Collection automatically letting us focus only on the applicationlogic.
We are also able tomanually trigger garbage collection by either calling System.gc() or Runtime.getRuntime().gc()methods, however the immediate execution is not guaranteed. Let's payour attention to check how Garbage Collection works in Java.
Javagarbage collector does automatic recycling of unused objects
Garbage Collector performsdynamic memory management
Java Garbage Collectorruns as a Daemon Thread (a low priority background thread) and it isresponsible for the following tasks.
· Keep trackof objects that are still in use (live) and those which are unused (which areeligible for removal).
· Recycleunused objects so that the occupied memory is available for reuse.
· Allocatememory to applications as per the requests and assign the released memory backto the OS.
Different algorithms can be usedfor Garbage Collection
In Java, differentGarbage Collector implementations use different algorithms and approaches forgarbage collection. Each of these algorithms have their own advantages andlimitations. Some of the algorithms divides heap memory in to two generationscalled young generation and old generation.
JVM has multiple implementationsof Garbage Collectors
In Java 7 to Java 13,there were four garbage collector implementations in JVM. In Java 14, there areonly three.
1.Concurrent Mark Sweep (CMS) Collector
Uses Mark Sweep algorithm inmultiple threads. This collector has been deprecated and unavailable since Java14.
2. SerialCollector
Uses Cheney’s copying algorithmand Mark Compact algorithm. Works on a single thread and freezes all otherthreads until garbage collection process is completed.
3. ParallelCollector
Uses the same algorithms as theSerial Collector, but runs on multiple concurrent threads. This was the defaultgarbage collector in Java 7 & 8.
4. G1Collector (Garbage-First Collector)
Segments heap in to multipleregions (typically 2048). Keeps track of live data in each region. Collects thegarbage first from the regions which have the most garbage. This is the defaultcollector since Java 9.
5. Class Unloading
Similar to how thememory occupied by unused Objects is reclaimed by the Garbage Collectionprocess, the classes which are loaded into the memory could be unloaded. Classunloading is an optimisation process performed by JVM to reduce the memoryusage.
A class will be typicallyunloaded once its defining Class Loader garbage is collected
Even if there are nocurrent references to a particular class, it will not be unloaded from memoryif its defining Class Loader is still reachable. This is because even if thereare no current references, it might be referenced by a class which ispotentially loaded by the loader. Also, if a class somehow unloaded from memorywhile its defining Class Loader is potentially reachable, the class may bereloaded in future, if the loader loads another class which has reference tothe said class.
Classes loaded by bootstraploader may not be unloaded
This is because, theinitial bootstrap class loader is permanently reachable throughout the JVMexecution. Therefore any classes that it loaded will not be unloaded untilprogramme exit.
We have discussed fivemajor JVM internal processes that are essential to run a Java application.Knowledge about JVM internals will be useful particularly when working with alarge scale enterprise application. Additionally, if you know how things areworking internally, you are more confident in writing robust code and resolvingany errors.
Thank You and Keeplearning!