Advanced-Programming

Runtime systems

Slides:

A runtime system implements the execution model of a programming language and provides a runtime support.

The runtime system can be made of:

The runtime support is needed for:

Java Runtime Environment (JRE)

Includes all what is needed to run compiled Java programs (bytecode).
It is made by the JVM and the JCL (Java Class Library, aka Java API).

Java Virtual Machine (JVM)

It is an abstract machine for the bytecode.
Oracle doesn’t provide details about the implementation of the JVS, but there are specifications for a machine independent class file format. Every language that can be compiled in a .class file can be executed by the JVM.

Each JVM has an internal representation (implementation dependent) of classes, objects and primitive types.

The JVM is a multithreaded stack-based machine.
Each instruction implicity take the arguments from and put the operands to the top of the operand stack of the current frame.
The operand stack stores also local variables and intermediate results.

Stack frames

Are often allocated on the heap and contains:

JVM Data Types

Primitive types:

Reference types:

Object representation

Is left to the implementation. Must include the concrete value of null, pointers to instance and class data, mutex locks and garbage collection flags.

JVM runtime data areas

JVM runtime data areas

Threads

Multiple threads are possible starting from a single main. Moreover, there are several background threads for garbage collection, signal dispatching, JIT compilation, etc.

Threads have shared access to heap and persistent memory. The latter includes the method area, interned strings, and code cache for JIT compilation.

Each thread has its separate stack area. That area includes:

Thread life-cycle

Thread life-cycle

Non-Heap: the Method Area

Contains:

Garbage collector

Is applied on the heap

  1. object and arrays are created into the young generation
  2. object alive are moved from the eden space to the survivor space
  3. survived object are moved into the old generation, the others deallocated
  4. every time the old generation is full is garbage collected (the young generation is garbage collected constantly)

Object finalization

Before deallocating an object, the Garbage Collector calls the finalize method. It is possible to override this method, although deprecated.

The finalization is called also on classes, usually when JVM exits. A class can be finalized only if no object of this class exists or the exist one are unrecheable.

JIT compilation

Since interpret bytecode is not as fast as execute native code, the JVM look for bytecode that is executed several time and compile it to native code. This code is stored in the code cache area of the non-heap memory area.

JVM Internals

Disassembling Java files

JVM startup

The linking consists in:

JVM Instruction set

Interpreter loop

  1. Calculate PC and fetch opcode
  2. if (operand) fetch operand
  3. execute op

Instruction format

Memory access

Different JVM data areas ⇒ different instruction for memory access:

Instruction examples