Tuesday, May 12, 2020

What Is Java Virtual Machine? Understanding JVM


Java language has its way to be run in a system. Unlike the flow of programming languages in general, to run Java code, the system must have a JVM (Java Virtual Machine) installed.

Understanding Java Virtual Machine

Java Virtual Machine is a special application installed to run Java programs on a computer or system.

The definition above is "simple version", because the Java Virtual Machine (we just call it a JVM), in theory, it's not only able to run applications written in the Java language, but also several other programming languages based on "Java bytecode".

Generally a desktop programming language has the following workflow (we use the C language example):
  • Write the program code using a text editor, then save for example as hello_world.c.
  • Compile the hello_world.c file into an object file named hello_world.o.
  • Perform a linker process, where the hello_world.o file is processed and produces an executable file named hello_world.exe (if it is intended for Windows operating systems).
  • The hello_world.exe file is ready to run.
The workflow above is a bit problematic in terms of portability. I mean, the hello_world.exe application can only run on Windows operating systems. If we want to run the same application on a Linux or Mac computer, the program code must be recompiled for each operating system.

The Java language development team wants to overcome this problem so that the Java language code is compiled only once and can run on all operating systems. Following is the process flow of creating and running programs written in Java:
  • Write the program code using a text editor, then save for example as hello_world.java
  • Compile the hello_world.java file into a byte code-named hello_world.class
  • The hello_world.class file can be run on all computers as long as the computer has a Java Virtual Machine installed.
The byte code in step 2 is similar to object code in other programming languages, but specifically the byte code is used to refer to object code that belongs to the Java language.

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:
  • Class Loader
  • Runtime Data Area
  • 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.

Programming Languages Running on the JVM

Designed by Rich Hickey, Clojure is a programming language similar to Scheme and Lisp that runs on the JVM. Clojure has quite a lot of interest among users of functional programming languages.

At first, Rich Hickey wanted the modern Lisp programming language for functional programming. He also wants a concurrent feature in that language. So at that time, Rich developed dotLisp, a Lisp project implemented on the .NET Framework. But finally, Rich developed Clojure which was implemented on the JVM. One well-known web framework designed using Clojure is Noir. The following is an example of the Clojure source code quoted from Wikipedia:

(let [i (atom 0)]
  (defn generate-unique-id
    "Returns a distinct numeric ID for each call."
    (swap! i inc)))

Groovy is a dynamic programming language similar to Python, Perl, Ruby, and Smalltalk that runs on Java. Groovy can interact with other Java libraries, and can create a blend of Java and Groovy.

Groovy has a famous web framework, Grails. Groovy was developed by James Strachan. Groovy is managed by a company called Pivotal. If you use Netbeans for the first time, you can see there are options for making an application with Groovy. Here is an example of the Groovy source code quoted from Wikipedia:

class AGroovyBean {
  String color

def myGroovyBean = new AGroovyBean()

myGroovyBean.setColor('baby blue')
assert myGroovyBean.getColor() == 'baby blue'

myGroovyBean.color = 'pewter'
assert myGroovyBean.color == 'pewter'

Jython is the JVM implementation of the Python programming language. It is designed to run on the Java platform. A Jython program can import and use any Java class. Just as Java, Jython program compiles to bytecode. One of the main advantages is that a user interface designed in Python can use GUI elements of AWT, Swing, or SWT Package. Some standard Python libraries cannot be accessed in Jython.

Jython was first developed by Jim Hugunin, Barry Warsaw, Samuele Pedroni, Brian Zimmer, and Frank Wierzbicki. The following is an example of Jython source code quoted from Jython Cookbook:

from javax.swing import JButton, JFrame

frame = JFrame('Hello, Jython!',
            defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
            size = (300, 300)

def change_text(event):
    print 'Clicked!'

button = JButton('Click Me!', actionPerformed=change_text)
frame.visible = True

JRuby was developed by Charles Oliver Nutter and Thomas Enebo. Initially JRuby was developed on Sun Microsystems but then moved to Engine Yard in 2009. In May 2012, the JRuby duo moved to Red Hat and focused more on developing JRuby. Two other contributors are Ola Bini and Nick Sieger. One of JRuby's advantages is the presence of multiple virtual machine collaboration features. The following is an example of the JRuby source code quoted from Wikipedia:

require 'java'

frame = javax.swing.JFrame.new
frame.getContentPane.add javax.swing.JLabel.new('Hello, World!')
frame.setDefaultCloseOperation javax.swing.JFrame::EXIT_ON_CLOSE
frame.set_visible true

Scala is claimed to be a simpler programming language compared to Java. One well-known web framework built using Scala is Lift and Scalatra. Scala was created by Martin Odersky. Martin wants a powerful functional programming language and also runs on the JVM. Besides, Martin was also involved in the development of the JVM with James Gosling and other JVM development teams. The following is an example of the Scala source code quoted from Wikipedia:

// Scala
class Point(
    val x: Double, val y: Double,
    addToGrid: Boolean = false
) {
  import Point._

  if (addToGrid)

  def this() = this(0.0, 0.0)

  def distanceToPoint(other: Point) =
    distanceBetweenPoints(x, y, other.x, other.y)

object Point {
  private val grid = new Grid()

  def distanceBetweenPoints(x1: Double, y1: Double,
      x2: Double, y2: Double) = {
    math.hypot(x1 - x2, y1 - y2)

The above programming language is among the many other programming languages implemented on the JVM. According to the List of JVM Language article on Wikipedia, there are around 60 programming languages developed on top of the JVM.

With a variety of specific characteristics and targets, JVM is the basis for other programming language developers to create their programming languages by relying on JVM as the foundation. So JVM isn't just for Java