Nach dem Milestone ist vor dem Milestone
Seit April arbeiten die Entwickler im JDK-7-Projekt am dritten Milestone (M3), der mit 7 Builds etwas länger ausfällt als M2. Das liegt einerseits daran, dass in dem dritten Milestone insgesamt fünf große Features zur Integration anstehen, und andererseits an der Notwendigkeit, eine stabile Preview des JDK 7 rechtzeitig zur JavaOne in die Hände der Java-Entwickler zu legen, damit sie sich mit den bereits integrierten Features vertraut machen können. Bereits enthalten im M1 sind seit Jahresanfang die komprimierten Objektzeiger. Sie sind ein VM-Feature, das sich auf 64-Bit-Systemen bemerkbar macht. Innerhalb der HotSpot JVM werden Zeiger auf Objekte von der virtuellen Maschine verwaltet. Dabei hängt die Größe eines Zeigers im Speicher üblicherweise von der Größe der Zeiger auf dem System ab – bei 32-Bit-Betriebssystemen 32 Bit, bei 64-Bit-Betriebssystemen entsprechend das Doppelte, womit auch der durch die Zeiger adressierbare Bereich deutlich über die bei 32-Bit-Systemen theoretisch maximal möglichen 4G hinausgeht. Das wiederum heißt, dass auf 64-Bit-Systemen Anwendungen mit einem immensen Speicherhunger laufen können, die auf kleineren Systemen früher oder später schnurstracks in einen OutOfMemoryError laufen würden. Daher gibt es das JDK auch für die meisten modernen Betriebssysteme in einer 32-Bit- und einer 64-Bit- Ausgabe.
Die meisten 64-Bit-Betriebssysteme erlauben jedoch den parallelen Betrieb von 32-Bit- und 64-Bit-Anwendungen, daher lässt sich z. B. unter Solaris zwischen einer als 32-Bit-Anwendung gebauten JVM und einer 64-Bit JVM mit den Kommandozeilenschaltern -d32 und -d64 umschalten. Wegen der Gesamtperformance kann das bei bisherigen JDK-Releases durchaus Sinn machen – für Anwendungen, deren Speicherhunger durch ein bis zwei Gigabyte Speicher völlig abgedeckt wird, brachte die 64-Bit JVM eher schlechtere Performance, durch den doppelt so hohen Speicherverbrauch für jeden von HotSpot verwalteten Objektzeiger. Mit modernen 64-Bit-Prozessoren, die wesentlich mehr Register als ihre 32-Bit-Gegenstücke der JVM bereitstellen können, wurde diese Entscheidung noch ein weniger komplizierter – für CPU-intensive Anwendungen, die von den zusätzlichen Registern profitieren können, fallen die Nachteile des höheren Speicherverbrauchs einer 64-Bit JVM gegenüber den Vorteilen weniger ins Gewicht.
Es wäre praktisch, wenn man die Entscheidung zwischen einer 32-Bit und einer 64-Bit JVM nicht treffen müsste und gleichzeitig die Vorteile des erweiterten Adressraums mit mehr Registern, die der JVM zur Verfügung stehen, mit einer kompakten internen Repräsentation der von der JVM verwalteten Objektzeiger verbinden könnte. Mit den komprimierten Objektzeigern wird unter 64-Bit-Systemen genau das gemacht – die internen Objektzeiger für Objektfelder und Elemente von Arrays von Objekten werden mit einem einfachen Trick auf 32-Bit komprimiert und bei Bedarf wieder auf 64-Bit expandiert. Dabei wird beim Komprimieren die Anfangsadresse des JVM-Hauptspeichers vom Objektzeiger abgezogen und das Ergebnis um drei Stellen nach rechts geschoben. In anderen Worten: die letzten drei Bits des ursprünglichen Objektzeigers fallen weg. Aber das macht gar nichts, denn auf 64-Bit Systemen befinden sich dort in JVM-Zeigern immer leere Bits, da die Adressen von Objekten im Hauptspeicher das Vielfache der Größe der Zeiger auf dem System sind – auf 64-Bit-Systemen also das Vielfache von acht.
Durch das Einsparen von drei Bits am „Ende“ eines Zeigers gewinnt man durch die Shift-Operation drei Bits am „Anfang“ des Zeigers, die nun in die komprimierte 32-Bit-Darstellung passen. Statt den unter 32-Bit-Systemen üblichen 4G, steigt der verfügbare Adressraum deswegen auf 32G von der Anfangsadresse des Hauptspeichers an. Die HotSpot-Kommandozeilenoption -XX:+UseCompressedOops schaltet das Feature ein, das bereits den Weg in die JDK 6u14 Early Access Releases gefunden hat. Weiterführende Arbeit an der HotSpot in OpenJDK hat zu noch besserer Performance geführt, sodass in Benchmarks die 64-Bit JVM nun in noch mehr Fällen die Nase vorn hat. Als weiteres HotSpot-Feature wurde im ersten Milestone der neue Garbage-First Garbage Collector (G1) integriert. Er hat ebenfalls bereits den Weg in die JDK 6u14 Early Access Releases gefunden. Wie für neue, experimentelle JVM-Technologien üblich, wird G1 mit den Kommandozeilenschaltern -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC aktiviert und verspricht guten Durchsatz bei niedriger Latenz. Also einfach mal ausprobieren, und im Fall von Bugs den Bugtracker füttern.
Im zweiten Milestone wurden ebenfalls zwei Features integriert. Michael McMahon hat die Klasse URLClassLoader um eine close()-Methode erweitert. Mit einem URLClassLoader lassen sich Klassen und Ressourcen über URL-Pfade ansprechen und laden. Von Haus aus werden die file-, jar- und HTTP-Protokolle unterstützt, die den Zugriff auf das lokale Dateisystem, JAR-Dateien und per http-Server erreichbare Dateisysteme ermöglichen. Die darunter liegenden Ressourcen, z. B. geöffnete Dateien auf dem lokalen Dateisystem, werden dank finalizer und Garbage Collection automatisch freigegeben und geschlossen. Da sich bis auf einige wenige Ausnahmen schwer voraussagen lässt, wann ein finalizer aufgerufen wird und z. B. bei Windows eine geöffnete Datei zuerst geschlossen werden muss, bevor sie ersetzt oder gelöscht werden kann, stellt das für Anwendungen, die beispielsweise dynamisch über gleich bleibende URLs Ressourcen neu laden wollen, eine Hürde dar, die nun mit der close-Methode einfach zu nehmen ist.
Das zweite große Feature, das seinen Weg ins JDK 7 bereits im Milestone 3 gefunden hat, ist das von Alan Bateman geleitete OpenJDK-NIO-Projekt, das die Referenzimplementierung für den JSR 203 beisteuert. Als JSR 203 Spec Lead hat Alan bereits Vorträge zu dem Thema gehalten, Interviews gegeben und garnierte die Integration mit einem Blogeintrag, in dem er auf die wichtigsten neuen Features eingeht. Mit kurzen Beispielen wurden die neuen APIs im neuen java.nio.File-Paket bereits von Eliotte Rusty Harold vorgestellt. Ein Paar davon, wie Path, DirectoryStream, Attributes, copyTo und moveTo werden für einige Java-Entwickler alltägliche Arbeitserleichterungen sein. Das NIO-Projekt bei OpenJDK ist ein Teil der Core Libraries Group. Um mehr externen Entwicklern einen Einblick in die aktuelle Entwicklungsarbeit an den Kernbibliotheken zu geben, trafen sich die daran beteiligten OpenJDK-Entwickler wie Josh Bloch, Doug Lea, Alan Bateman und Mark Reinhold zu einem runden Tisch. Die Aufnahmen sind, wie für OpenJDK üblich, am nächsten Tag online gewesen – weitere Treffen werden in loser Folge stattfinden.
Sechser mit Zusatzzahl
Da es mit Java SE 6u13 ein Release gab, in dem diverse Sicherheitslücken gestopft wurden, gibt es auch ein entsprechendes Update von OpenJDK 6. Im Build 16 wurden außerdem diverse kleinere Bugs gefixt und Patches von IcedTea integriert. Mein Lieblingsfix in diesem Build ist jedoch mein eigener – der für den Bug 6781572. Dadurch wird es noch ein wenig einfacher, selbst Hand anzulegen, das OpenJDK zu bauen und mit den eigenen Bugfixes loszulegen.
Links & Literatur
- http://wikis.sun.com/display/HotSpotInternals/CompressedOops
- http://java.sun.com/docs/hotspot/HotSpotFAQ.html#gc_heap_32bit
- http://java.sun.com/docs/hotspot/HotSpotFAQ.html#64bit_performance
- http://blogs.sun.com/nike/entry/compressed_object_pointers_in_hotspot
- http://blog.juma.me.uk/2008/10/14/32-bit-or-64-bit-jvm-how-about-a-hybrid/
- http://blog.juma.me.uk/2009/04/03/load-unsigned-and-better-compressed-oops/
- http://www.infoq.com/news/2009/04/g1
- http://bugreport.sun.com/
- https://jdk6.dev.java.net/6uNea.html
- http://blogs.sun.com/michaelmcm/entry/closing_a_urlclassloader
- http://download.java.net/jdk7/docs/api/java/net/URLClassLoader.html#close()
- http://openjdk.java.net/projects/nio/
- http://jcp.org/en/jsr/detail?id=203
- http://www.youtube.com/watch?v=yNRS1ssLPdQ
- http://www.artima.com/lejava/articles/more_new_io.html
- http://blogs.sun.com/alanb/entry/jsr_203_nio2_update
- http://today.java.net/pub/a/today/2008/07/03/jsr-203-new-file-apis.html















