Understanding Java Virtual Machine

Giovanni Sakti
AbstractLayers
Published in
4 min readJan 22, 2018

There is a common misconception back in the day that JavaScript and Java programming languages (abbr. javalang) are somewhat related to each other, which is entirely untrue (the only relation is that they have similar names).

And there is also other piece of technology, which is sometimes closely associated with javalang but actually getting more and more decoupled nowadays called the Java Virtual Machine (abbr. JVM).

Official logo of javalang

To understand more about JVM, first we have to know a bit of its history. JVM was created out of requirement for javalang, which have portability as one of its main concern. Back in early 90s, the common option for compiled languages to execute was to compile it first into machine-readable codes for each specific platforms. So if we want portability, we have to use interpreted languages, but it is order(s) of magnitude slower.

As a solution to that issue, the JVM was created. JVM is an abstract virtual machine used as compilation target for javalang. It means that we compile our javalang codes into codes that JVM understand (instead of compiling it into multiple & specific machine-readable codes). If you already familiar with javalang, we use the javac compiler for that purpose.

James Gosling, founder and lead designer of javalang (including JVM)

Codes that JVM understand is called the Java bytecode, essentially an Intermediate Representation (abbr. IR) of our javalang codes. Java bytecode is portable, can be moved into different machines and be executed without recompiling.

If you’re previously coming from .NET, they also have similar virtual machine just like JVM called Common Language Runtime (abbr: CLR). Therefore this kind of code execution technique isn’t only exclusive to Java.

Components of JVM

As compilation target and virtual machine, JVM try to mimic our computer in its architecture, such as by having memory management system and register.

JVM has 3 essential components:

  1. Class Loader
  2. Runtime Data Area
  3. Execution Engine

The portable java bytecode are stored in our computer as files with *.class extension. Therefore the first component of JVM is responsible for loading all *.class files, hence why it’s called the class loader. It is also responsible for verifying whether the supplied bytecodes are valid and resolving all static references.

Runtime data area responsible for storing all classes, objects, methods, variables and its data. Basically this is the component that mimic our computer memory. But it also have PC registers as sub-component, which stores the address of current executing instruction (essentially similar to register in our CPU).

Lastly and perhaps the most important, execution engine responsible for executing the bytecodes. It contains an interpreter, just-in-time compiler (abbr. JIT compiler) and garbage collector.

You may wonder why JVM has both compiler and interpreter. On early version of JVM the execution engine only has interpreter to execute the bytecode. The JIT compiler was added later to increase performance. Basically the JVM can now dynamically increase performance by identifying methods that are used often in our program. JVM then ask the JIT compiler instead to compile those methods instead of re-interpreting it every time. This is why JVM performance benefits quite significantly from warm-up time.

The JVM Languages

From purely technical standpoint, JVM understand java bytecode, but it does not understand about javalang at all. Therefore we can view javalang and JVM as a separate entity. In fact, when JVM usage getting more widespread and its features and performance getting more powerful, emerge implementations of programming languages other than javalang that can be compiled into java bytecode. Some of the more famous examples are Scala, Kotlin, Clojure, JRuby and Jython.

Summary

  1. JVM is an abstract virtual machine runs on top of your computer.
  2. JVM acts as compilation target for JVM languages. The first JVM language created is the javalang.
  3. JVM understands and can execute the java bytecode.
  4. JVM has 3 main components: the class loader, runtime data area and execution engine. As a virtual machine, JVM try to mimic our computers in its architecture.
  5. There are also languages other than javalang that can be compiled into java bytecode, called the JVM languages.

--

--

Giovanni Sakti
AbstractLayers

Current: Engineering Management & Leadership, Consultant, Livestream (ID) insinyur.online, Nonprofit (ID) deeptech.id | bio.link/giosakti