Garbage Collection mit Stackmaps

Der Einsatz von Java in eingebetteten Systemen hat in den letzten Jahren stark zugenommen. Dabei bestehen auf diesem Einsatzgebiet besondere Restriktionen bezüglich Speicher- und Resourcennutzung. Eine effiziente JVM für eingebettete Systeme ist die Kertasiere VM. Aktuell (Stand August 2005) implementiert diese JVM allerdings noch keine vollständige Garbage Collection, sodass es hier zu Speicherlecks kommen kann. Dieser Aufgabe widmete sich eine Gruppe von drei Leuten im Rahmen des Praktikums zur Vorlesung "Java in eingebetteten Systemen" im Sommersemester 2005 an der TU-Dresden.

Stackmaps

Beim Einlesen einer Klassendatei kann mit entsprechenden Methoden die Klasse analysiert werden und es kann eine Belegungsmarkierung für jede Stackposition ermittelt werden. Diese gibt an in welchen Bytecodeintervallen an dieser Stackposition eine Referenz abgelegt ist. Der Garbage Collector kann diese Informationen nutzen, um Referenzen zu verfolgen und damit nicht mehr referenzierten Speicher zu ermitteln und freizugeben.

Aufgrund der meist geringeren Verfügbarkeit an Resourcen (hauptsächlich Hauptspeicher und Prozessorleistung) in eingebetteten Systemen wäre eine Ermittlung dieser Belegungen zur Laufzeit des Programms (konkret beim Laden der benötigten Klassendatei) nicht effektiv durchführbar. Glücklicherweise kann diese Bestimmung auch direkt bei der Programmerzeugung, sozusagen offline, durchgeführt werden. Für unserer Projekt übernimmt diese Aufgabe das Programm mapgen einer Praktikumsgruppe aus dem letzten Jahr.

Garbage Collection in der Kertasarie VM

Die Kertasarie-VM unterstützt zwei Modi von Garbage Collection: einen nicht echtzeitfähigen und einen echtzeitfähigen. Bei letzterem wird die Echtzeitfähigkeit durch Unterbrechbarkeit des GC-Prozess ermöglicht. Beiden Modi ist gemeinsam, dass sie nur eine konservative Garbage Collection implementieren.

Struktur der Stackmaps

Das Werkzeug mapgen fügt einer Klassendatei die Attribute KertasarieLocalMap für den Stack der lokalen Variablen und KertasarieStackMap für den Stack hinzu. Die Struktur dieser Attribute sieht dabei wie folgt aus:

attribute_byteValues
{
  u2 maximale Stacktiefe n
  n*u4 Zeiger auf Eintrag für n-te Stackposition
  Eintrag für n-te Stackposition
  {
    u2 Anzahl der Bytecodeintervalle k
    k*u4 Bytecodeintervall
  }
}

Bytecodeintervall sieht wie folgt aus:

Bytecodeintervall
{
  u2 Intervallstart
  u2 Intervallende
}

Diese Attribute werden jetzt vom Klassenlader der Kertasarie VM eingelesen und in einer entsprechenden Struktur abgelegt. Diese Datenstruktur ist über Felder in der Methodenstruktur für den Garbage Collector verfügbar. Bei einem Zyklus kann dieser nun endgültig entscheiden, welche Speicherobjekte Referenzen sind und welche nicht und damit vollständige Garbage Collection durchführen.

Dabei ist die Implementierung echtzeitfähig geblieben. Es muss lediglich die Kallibrierung neu durchgeführt werden.