
10 Types of Programming Languages Every Coder should Know
Learn about different types of programming languages and how they are implemented in the real world.
A Java Virtual Machine (JVM) allows Java to be a cross-platform language. It acts as a virtual engine that decodes and runs Java programs in ByteCode format irrespective of the Operating system and particular features of the target platform.
For developers, the knowledge of the JVM architecture allows writing more efficient code, improving its performance, and resolving issues. However, this is not just any process of executing the program but rather entails critical tasks of memory management and garbage collection.
In this blog, we will discuss the most important elements of the JVM like memory areas, class loaders, the execution engine, garbage collection, and performance optimisation techniques.
JVM stands for Java Virtual Machine and is defined as a software power engine for executing Java programs. Its key function is to transform Java’s bytecode into low-level commands that are unique to a given system’s hardware, assuring that the Java-based applications can run on different systems.
Based on the idea of a ‘write once, run everywhere’ concept of Java, the JVM guarantees that the Java code can be executed on any computer system with a compatible JVM installed. Hence, programmers do not have to perform modification or recompilation of codes for the various operating systems.
As an intermediary between compiled bytecode and machine code, the JVM is responsible for memory management, garbage collection and security checks. This intermediary role makes sure that the program executes in the most efficient manner without compromising on a stable runtime environment.

POSTGRADUATE PROGRAM IN
Multi Cloud Architecture & DevOps
Master cloud architecture, DevOps practices, and automation to build scalable, resilient systems.
Here, we have explained 5 components of the JVM architecture.
The JVM loads classes dynamically, meaning classes are only brought into memory when needed during program execution. This dynamic class loading allows Java programs to run efficiently by loading resources on demand rather than all at once. The process of class loading is handled by the ClassLoader subsystem, which ensures that classes are available when required.
The class loading process consists of three main steps: Loading, Linking, and Initialisation.
2. Linking:
2.1 Linking consists of three sub-steps: Verification, Preparation, and Resolution.
3. Initialisation:
Also Read: Difference Between JDK, JRE and JVM
The following example demonstrates how the JVM loads a class dynamically using the Class.forName() method.
public class ClassLoadingExample {
public static void main(String[] args) {
try {
// Dynamically load the class
Class<?> clazz = Class.forName("java.util.ArrayList");
System.out.println("Class loaded successfully: " + clazz.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Explanation:
Classes in Java are loaded on demand which means that there is no need to load a class until it is used for the first time. Let’s say that a method within a class is not called, the class may not get loaded at all. This method helps improve memory usage and performance of the program as the loading of classes that are not needed does not take place.
The hierarchical delegation model used in class loading ensures that classes are loaded in a specific order:
By following this process, the JVM ensures that classes are available for execution as needed, without overloading memory with unnecessary resources.
The JVM organises memory into various runtime data areas, each with a specific purpose. These memory areas store data and execution information necessary for running Java programs.
2. Heap:
3. Stack Area:
4. Program Counter (PC) Register:
5. Native Method Stack:
The execution engine is responsible for executing Java bytecode. It consists of multiple components that work together to convert bytecode into machine-specific instructions and execute them.
1. Interpreter:
2. Just-In-Time (JIT) Compiler:
Example Code: Performance Improvement with JIT
public class JITExample {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
int square = i * i;
}
long end = System.currentTimeMillis();
System.out.println("Time taken: " + (end - start) + " ms");
}
}
In this example, the JIT compiler will optimise the loop to improve execution speed.
3. Garbage Collector (GC):
The Native Method Interface (JNI) is able to bridge the gap between Java code and applications or libraries written in C or C++. This ability proves useful in situations where there is a need to interface with platform-specific features or legacy systems.
To use JNI, we create a native method in Java, implement it in C, and load the native library using System.loadLibrary in Java.
public class NativeExample {
static {
System.loadLibrary("nativeLib");
}
// Declaration of native method
public native void sayHello();
public static void main(String[] args) {
new NativeExample().sayHello();
}
}
Native method libraries are loaded when a native method is called. These libraries allow Java programs to execute platform-specific operations that cannot be implemented in pure Java.
Optimising JVM performance ensures that Java applications run efficiently. This involves tuning JVM settings, using monitoring tools, and optimising code. Here’s how to achieve better JVM performance.
JVM tuning involves configuring settings like memory allocation, garbage collection, and JVM parameters to boost performance.
1. Memory Tuning:
2. Selecting the Right Garbage Collector:
2.1 Use suitable garbage collection algorithms based on the application’s requirements:
3. Tuning JVM Parameters:
Monitoring tools are essential for tracking JVM performance, enabling developers to identify and fix bottlenecks.
Efficient coding practices play a significant role in JVM performance. Here are key techniques:
Example:
// Inefficient
for (int i = 0; i < myList.size(); i++) { ... }
// Optimised
int size = myList.size();
for (int i = 0; i < size; i++) { ... }
Also Read: HashMap in Java
Running a Java program involves several steps, from writing the code to executing it on the JVM. Here’s a simple example to demonstrate the process.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
javac HelloWorld.java
java HelloWorld

82.9%
of professionals don't believe their degree can help them get ahead at work.
An OutOfMemoryError or other memory issues arise when there is not sufficient heap space available.
import java.util.ArrayList;
import java.util.List;
public class MemoryLeakExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
while (true) {
list.add("This will cause a memory leak");
}
}
}
The above code causes an OutOfMemoryError as it continuously adds data to the list without releasing memory.
High CPU usage can be linked to inefficient code or poor garbage collection settings. Profiling tools help pinpoint bottlenecks.
public class HighCPUExample {
public static void main(String[] args) {
while (true) {
// Inefficient loop consuming CPU
System.out.println("Busy loop");
}
}
}
Several common errors can occur while running Java programs. Understanding their causes and solutions helps in troubleshooting.
This occurs when the JVM cannot allocate enough memory. This can be due to memory leaks, large data structures, or insufficient heap size.
Example Trigger:
int[] largeArray = new int[Integer.MAX_VALUE];
Solution: Increase heap size (-Xmx), optimise memory usage, or use a different garbage collector.
This Happens when the stack size is exceeded, typically due to deep or infinite recursion.
Example Trigger:
public class StackOverflowExample {
public static void main(String[] args) {
recursiveMethod();
}
public static void recursiveMethod() {
recursiveMethod(); // Infinite recursion
}
}
Thrown when the JVM cannot find the specified class during dynamic loading.
Example Trigger:
Class.forName(“com.nonexistent.Class”);
Also Read: Java Interview Questions and Answers
Developers who want to deal with performance problems and optimise their applications must have knowledge of the architecture of the JVM. The importance of the JVM in memory, garbage collection and execution makes it essential to know how it works internally.
JVM settings can be enhanced by understanding fundamental principles like class loading, parameters of memory zones, and garbage collection which in turn will enhance Java developers’ coding ways. This knowledge also ensures that Java programs are well-optimised and the development process is carried out in the most efficient way possible. Try the Certificate Program in Application Development by Hero Vired to explore Java in detail
Updated on October 23, 2024

Learn about different types of programming languages and how they are implemented in the real world.

Explore 10 front-end development, including key languages, its advantages and disadvantages, and how it shapes user experience in web design and functionality.