Die Architektur der Java VM

Jan Bernitt

Virtualisierungsziele

Java Laufzeit-System
Java Runtime Environment (JRE)

Java Virtual Maschine (JVM)

Application and Programming Interface (API)

Die Java VM

Java ClassLoader

JVM (Execution Engine)
erfragt unbekannte Klasse
SystemClassLoader
nicht gefunden: delegiert an
ExtendsionClassLoader
nicht gefunden: delegiert an
BootStrapClassLoader
löst aus: ClassNotFoundException

Ziel:

Automatische Speicherverwaltung
Garbage Collection

Strategien:

GC aus Sicht des Programmierers

Execution-Engine
"virtueller Prozessor"

Funktionsweise: ...später im Detail

Optimierungen:

Das .class-Dateiformat
ClassFile-Tabelle

magic = 0xCAFEBABE
minor_version
major_version
constant_pool_count
ConstantPool[]
access_flags
this_class
super_class
interface_count
interface_index[]
field_count
Field[]
method_count
Method[]
attribute_count
Attribute[]
2.1: Zugriffs- und Eigenschafts-Flags von Klassen
NameWertBeschreibung
ACC_PUBLIC0x0001Klasse ist als public deklariert, daher Zugriff auch von außerhalb ihres Pakets erlaubt.
ACC_FINAL0x0010Klasse ist als final deklariert, keine Unterklassen erlaubt.
ACC_SUPER0x0020Besondere Behandlung für Methoden der Superklasse beim Aufruf über invokespecial.
ACC_INTERFACE0x0200class-File beschreibt ein Interface, keine Klasse. ACC_ABSTRACT erforderlich.
ACC_ABSTRACT0x0400Klasse ist als abstract deklariert, daher keine Instanziierung erlaubt.
ACC_SYNTHETIC0x1000Klasse ist vom Compiler generiert, im Quellcode nicht vorhanden.
ACC_ANNOTATION0x2000class-File beschreibt eine Annotation, keine Klasse. ACC_INTERFACE erforderlich.
ACC_ENUM0x4000Diese Klasse (oder ihre Superklasse) ist als Aufzählungstyp enum definiert.

Das .class-Dateiformat
ConstantPool-Tabelle

CONSTANT_Utf8
tag = 1
length
bytes[]
CONSTANT_Integer
tag = 3
bytes
CONSTANT_Float
tag = 4
bytes
CONSTANT_Long
tag = 5
high_bytes
low_bytes
CONSTANT_Double
tag = 6
high_bytes
low_bytes
CONSTANT_Class
tag = 7
name_index→1
CONSTANT_String
tag = 8
string_index→1
CONSTANT_Fieldref
tag = 9
class_index→7
name_type_index→12
CONSTANT_Methodref
tag = 10
class_index→7
name_type_index→12
CONSTANT_InterfaceMethodref
tag = 11
class_index→7
name_type_index→12
CONSTANT_NameAndType
tag = 12
name_index→1
descriptor_index→1

Namen und Typen innerhalb der JVM

Das .class-Dateiformat
Field und Method-Tabelle

access_flags
name_index→1
descriptor_index→1
attributes_count
7.1: Zugriffs- und Eigenschafts-Flags von Feldern
NameWertBeschreibung
ACC_PUBLIC0x0001Feld ist als public deklariert, daher Zugriff auch von außerhalb des Pakets erlaubt.
ACC_PRIVATE0x0002Feld ist als private deklariert, daher Zugriff nur in der definierenden Klasse.
ACC_PROTECTED0x0004Feld ist als protected deklariert, daher Zugriff auch in Unterklassen der definierenden Klasse.
ACC_STATIC0x0008Feld ist als static deklariert, also eine Klassenvariable (ohne) oder Konstante (mit) ACC_FINAL.
ACC_FINAL0x0010Feld ist als final deklariert, daher keine weitere Zuweisung nach Initalisierung möglich.
ACC_VOLATILE0x0040Feld ist als volatile deklariert, daher kein cachen des Werts möglich.
ACC_TRANSIENT0x0080Feld ist als transient deklariert, daher kein lesender oder schreibender Zugriff vom PersistentObjectManager.
ACC_SYNTHETIC0x1000Feld ist vom Compiler generiert, im Quellcode nicht vorhanden.
ACC_ENUM0x4000Feld wird verwendet, um einen Wert eines Aufzählungstyp zu speichern.
7.2: Zugriffs- und Eigenschafts-Flags von Methoden
NameWertBeschreibung
ACC_PUBLIC0x0001Methode ist als public deklariert, daher Aufruf auch von außerhalb des Pakets erlaubt.
ACC_PRIVATE0x0002Methode ist als private deklariert, daher Aufruf nur in der definierenden Klasse möglich.
ACC_PROTECTED0x0004Methode ist als protected deklariert, daher Aufruf auch in Unterklassen der definierenden Klasse erlaubt.
ACC_STATIC0x0008Methode ist als static deklariert, also eine Klassenmethode.
ACC_FINAL0x0010Methode ist als final deklariert, kann nicht überschrieben werden.
ACC_SYNCHRONIZED0x0020Methode ist als synchronized deklariert, daher Aufruf über einen Monitor.
ACC_BRIDGE0x0040Methode wurde als Bridge-Methode (Type Erasure) vom Compiler erzeugt.
ACC_VARARGS0x0080Methode wurde im Quellcode mit variabler Parameteranzahl deklariert.
ACC_NATIVE0x0100Methode ist als native deklariert, wird daher in einer anderen Sprache als Java-Bytecode implementiert.
ACC_ABSTRACT0x0400Methode ist als abstract deklariert, besitzt daher keine Implementierung.
ACC_STRICT0x0800Methode ist als strictfp deklariert, verwendet daher den Gleitkomma-Modus FP-strict.
ACC_SYNTHETIC0x1000Methode ist vom Compiler generiert, im Quellcode nicht vorhanden.

Descriptoren und Signaturen

Descriptoren:

Signaturen:

5.1: Bedeutung der BaseType-Zeichen
BaseType-ZeichenTypBedeutung
Bbytevorzeichenbehafteter Bytewert
CcharUnicode-Zeichen
DdoubleFließkommawert mit doppelter Genaigkeit
FfloatFließkommawert mit einfacher Genauigkeit
Iintvorzeichenbehafteter Integerwert
Jlongvorzeichenbehafteter Longwert
LClassname;referenceEine Instanz der Klasse Classname
Sshortvorzeichenbehafteter Shortwert
Vvoidentspricht dem Rückgabewert void
Zbooleantrue oder false
[referenceEine Array-Dimension

Attribute und Annotations

Attribute:

name_index→1
length
info[]

Annotations:

Das .class-Dateiformat
Das Code-Attribut

name_index→1
length
max_stack
max_locals
code_length
code
exceptions_count
attributes_count

Die Exception-Tabelle

start_pc
end_pc
handler_pc
catch_type→7

Das .class-Dateiformat
Einfache Attribute

Synthetic
name_index→1
length = 0
Deprecated
name_index→1
length = 0
Signature
name_index→1
length = 2
signature_index→1
SourceFile
name_index→1
length = 2
sourcefile_index→1
ConstantValue
name_index→1
length = 2
constant_value_index
9.1: Attribut ConstantValue Typen-Index
attributierter Feld-Typconstant_value_index→RCP-Eintrag
longCONSTANT_Long →5
floatCONSTANT_Float →4
doubleCONSTANT_Double →6
int,short,char,byte,booleanCONSTANT_Integer →3
StringCONSTANT_String →8

Befehlssatz des Bytecodes (1)

Load & Store

Arithmetik

Kontrolltransfer:

Befehlssatz des Bytecodes (2)

VerwendungOpcode Mnemonics
Daten-OPs
"Load & Store"
Stack ⇔ Stack nop, pop, pop2, dup, dup_x1, dup_x2, dup2, dup2_x1, dup2_x2, swap
Konstante ⇒ Stack aconst_null,
iconst_<n> (iconst_m1, iconst_0, iconst_1, iconst_2, iconst_3, iconst_4, iconst_5),
lconst_<n> (lconst_0, lconst_1),
fconst_<n> (fconst_0, fconst_1, fconst_2),
dconst_<n> (dconst_0, dconst_1)
bipush, sipush, ldc, ldc_w, ldc2_w,
Variable ⇒ Stack iload, iload_<n> (iload_0, iload_1, iload_2, iload_3)
lload, lload_<n> (lload_0, lload_1, lload_2, lload_3)
fload, fload_<n> (fload_0, fload_1, fload_2, fload_3)
dload, dload_<n> (dload_0, dload_1, dload_2, dload_3)
aload, aload_<n> (aload_0, aload_1, aload_2, aload_3)
Stack ⇒ Variable istore, istore_<n> (istore_0, istore_1, istore_2, istore_3)
lstore, lstore_<n> (lstore_0, lstore_1, lstore_2, lstore_3)
fstore, fstore_<n> (fstore_0, fstore_1, fstore_2, fstore_3)
dstore, dstore_<n> (dstore_0, dstore_1, dstore_2, dstore_3)
astore, astore_<n> (astore_0, astore_1, astore_2, astore_3)
Arraywert ⇒ Stack iaload, laload, faload, daload, aaload, baload, caload, saload
Stack ⇒ Arraywert iastore, lastore, fastore, dastore, aastore, bastore, castore, sastore
Variablen iinc, wide
Arrays newarray, anewarray, arraylength, multianewarray
Objekte getstatic, putstatic, getfield, putfield, new, checkcast, instanceof

Befehlssatz des Bytecodes (3)

Arithmetik
"ALU"
Ganzzahlen iadd, isub, imul, idiv, irem, ineg,
ladd, lsub, lmul, ldiv, lrem, lneg
Gleitkomma fadd, fsub, fmul, fdiv, frem, fneg,
dadd, dsub, dmul, ddiv, drem, dneg
Bitweise ishl, ishr, iushr, iand, ior, ixor,
lshl, lshr, lushr, land, lor, lxor
Typumwandlung i2l, i2f, i2d, i2b, i2c, i2s,
l2i, l2f, l2d,
f2i, f2l, f2d,
d2i, d2l, d2f
Flusskontrolle Sprünge lcmp, fcmpl, fcmpg, dcmpl, dcmpg,
ifeq, ifne, iflt, ifge, ifgt, ifle,
if_icmpeq, if_icmpne, if_icmplt, if_icmpge, if_icmpgt, if_icmple,
if_acmpeq, if_acmpne, ifnull, ifnonnull,
goto, goto_w
Unterprogramme jsr, ret, jsr_w
Tabellen tableswitch, lookupswitch
Methoden invokevirtual, invokespecial, invokestatic, invokeinterface,
ireturn, lreturn, freturn, dreturn, areturn, return
Exceptions athrow
Threads monitorenter, monitorexit

JVM zur Laufzeit
Objekterzeugung - new

JVM zur Laufzeit
Feldzugriff

JVM zur Laufzeit
Konstanten

JVM zur Laufzeit
Klassen-Methoden (1)

JVM zur Laufzeit
Klassen-Methoden (2)

JVM zur Laufzeit
Interface-Methoden

JVM zur Laufzeit
Dynamisches Binden von Methoden

Vorbedingung:

Initalisierung:

Suche (Lookup-Algorithmus):

  1. Enthält C Instanz-Methode MMCP, wird M aufgerufen, sonst 2.
    (nur invokevirtual: M muss für C zugreifbar sein)
  2. Hat C eine Superklasse S, wird das Lookup rekursive für S ausgeführt, sonst AbstractMethodError.

JVM zur Laufzeit
Exception-Kontrolltransfer

JVM zur Laufzeit
Unterprogramme

Befehle:

Ablauf:

  1. Ausführen von jsr(_w):
    Offest der nachfolgenden Anweisung wird als returnAddress auf OS gebracht
    fortsetzen bei relativem Offest des jsr(_w)-Befehls (Unterprogramm)
  2. Ausführen des Unterprogramms:
    sichern der returnAddress in LV i
    ...Unterprogrammanweisungen...
  3. Ausführen von ret:
    schreiben der returnAddress aus LV i in PC des Threads
    fortsetzen mit Befehl bei PC

Der Bytecode-Verifier

Aufgabe

Erreicht:

Bedingungen:

Bewertung