Building a Virtual Machine, JVM-inspired (Intro)

Ondrej Kvasnovsky
2 min readJan 3, 2025

--

Have you ever wondered how the Java Virtual Machine (JVM) works under the hood? While the real JVM is an incredibly complex piece of software, we can learn a lot by building a simplified version ourselves.

In this series, we’ll create a tiny virtual machine that demonstrates core concepts like thread management, multithreading, memory models, mutex, compilation, byte-code execution, function call stacks, both local and global scopes (heap), and even garbage collection.

What we are going to build

We are going to build a simplified virtual machine called TinyVM. The name TinyVM simply reflects its minimalistic implementation and is not a reference to any existing projects.

We’ll implement it in several parts to focus on one concept at a time. We’ll use C language to mimic JVM functionality, with detailed explanations of the code.

Part 1 — Foundations

  • Variable assignment and manipulation with integer values
  • Basic arithmetic operations between variables
  • Console output functionality (print function)
  • Thread sleep operations

Part 2 — Multithreading

  • Implementation of real threads for concurrent code execution

Part 3 — Heap

  • Implementation of globally shared variables accessible across all threads

Part 4 — Synchronized

  • Implementation of mutex (mutually exclusive locks) to prevent race conditions in concurrent threads

Part 5 — Refactoring

  • Code organization into modules like core, instructions, memory, thread, etc.

Part 6 — Functions

  • Support for both synchronous (sequential) and asynchronous (threaded) function execution

Part 7— Compilation

  • Introduction of byte-code compilation support

Part 8 — Byte-code execution

  • Implementation of byte-code loading and execution

Part 9 — Function call stack

  • Implementation of function call stack for tracking execution order in chained functions

Part 10 — Garbage collector

  • Implementation of a basic mark-and-sweep garbage collector to automatically manage memory and clean up unreferenced objects

What we won’t build

To maintain focus on thread management, the following features will not be implemented:

  • Class loading and Java parsing/compilation to byte-code
  • Complex data types (integers only)
  • Exception handling
  • Performance optimizations
  • Advanced programming practices

The short sum-up to read

Before continuing with building our Virtual Machine, I recommend reading about JVM’s basic building blocks, memory organization, and thread operations in this article:

Next steps

  1. Part 1 — Foundations
  2. Part 2 — Multithreading
  3. Part 3 —Heap
  4. Part 4 — Synchronized
  5. Part 5 — Refactoring
  6. Part 6 — Functions
  7. Part 7 — Compilation
  8. Part 8 — Byte-code execution
  9. Part 9 — Function call stack (not started)
  10. Part 10 — Garbage collector (not started)

--

--

No responses yet