Interview mit Peter Lawrey und Christoph Engelbert

„Wir sollten darüber nachdenken, Java 9 zu überspringen“

Hartmut Schlosser

© Shutterstock.com/Fernando Sanchez Cortes

Die Pläne, das weit verbreitete sun.misc.Unsafe API aus Java 9 zu entfernen, stoßen auf Widerstand aus der Community. Diskutiert wird derzeit ein Vorschlagspapier, das Alternativen für das reine Entfernen von Unsafe aufzeigen soll. Wir haben uns mit den Initiatoren des Lösungsvorschlags Christoph Engelbert (Hazelcast) und Peter Lawrey (OpenHFT) unterhalten.

JAXenter: Es gibt den Plan, sun.misc.Unsafe im JDK 9 für Nutzer unzugänglich zu machen. Was ist eigentlich der Grund dafür?

Christoph Engelbert: Zunächst einmal denke ich, dass diesem Plan niemand wirklich widerspricht. Das API ist furchtbar und war von Beginn an nicht zur allgemeinen Nutzung vorgesehen. Aber faktisch war es verfügbar und wurde auch genutzt. Lass mich etwas später darauf zurückkommen.

Einer der Gründe für das Entfernen von sun.misc.Unsafe ist das Ziel, Java sicherer zu machen. Mit sun.misc.Unsafe sind beliebige Speicherzugriffe ohne Bounding-Checks auch innerhalb des nativen Codes des JIT Compilers möglich.

Peter Lawrey: Obwohl das API kein Standard war, wurde es aus verschiedenen Gründen genutzt. Entweder:

  • weil es einfach da war,
  • weil es Spaß gemacht hat,
  • weil es besser war als JNI zu nutzen
  • oder weil es wirklich keine Alternative gab.

Lange Zeit schienen die API Designer zu denken, dass die Leute sun.misc.Unsafe ohne echten Grund, quasi aus Spaß an der Sache nutzten. Sie konnten sich einfach nicht vorstellen, warum es irgend jemand außer sie selbst nützlich finden würde. Ich finde es schon etwas seltsam, dass die API Designer Unsafe definitiv für die Implementierung von Low-Level-Bibliotheken brauchten und scheinbar vermuteten, dass sonst niemand Low-Level-Bibliotheken schreiben würde.

Jetzt stellen sie kurz vor dem Release von Java 9 fest, dass sie Unsafe nicht einfach entfernen können, weil es an zu vielen Stellen eingesetzt wird. Es gibt tatsächlich nur sehr wenige interne APIs, die von so vielen Bibliotheken genutzt werden.

Eine Anmerkung noch: Das tools.jar wurde mit relativ wenig Bedenken entfernt, vor allem weil hier ein besserer Ersatz zur Verfügung stand: das Compiler API – und das gab es schon eine ganze Weile.

Chris: Ich vermute, Unsafe ist das meistgenutzte interne API, dessen Entfernung uns bevorsteht, nicht nur im Java-Ökosystem. Wie Peter schon gesagt hat, werden viele Dinge in Java 9 verschwinden. sun.misc.Unsafe ist wahrscheinlich das am weitesten verbreitete davon, aber nicht das einzige. Das OpenJFX-Projekt zum Beispiel nutzt immer noch Klassen von com.sun.javafx, da der Code noch nicht Open Source ist. Das bedeutet, dass auch OpenJFX mit Java 9 nicht ohne weiteres funktionieren wird.

JAXenter: Die Community zeigt einigen Widerstand gegen das Entfernen von Unsafe. Welche Probleme werden in den Diskussionen genannt?

Chris: Wie schon erwähnt, war das sun.misc.Unsafe API immer verfügbar und wurde deshalb auch häufig genutzt. Es gibt ein Menge verschiedener Gründe und Anwendungsfälle für den Einsatz von sun.misc.Unsafe, beispielsweise die Serialisierung, Performanz, Latenz, Mocking Frameworks, etc. Wenn das Unsafe-API von Beginn an nicht verfügbar gewesen wäre, würde das Java-Ökosystem heute wohl anders aussehen.

Peter: Es gibt dabei zwei Probleme. Zum einen wollen die Nutzer der Bibliotheken ihre Anwendungen nicht kaputt machen und werden deshalb möglicherweise nicht zu einem Upgrade auf Java 9 bereit sein. Sie wollen die Migration so geschmeidig wie möglich vollziehen. Wenn sie sich dann aber um JVM-Änderungen und Bibliotheks-Updates Sorgen machen müssen und gleichzeitig wenige Vorteile in Java 9 geboten bekommen, wird ein Upgrade noch unwahrscheinlicher. Möglicherweise werden mehr Leute gleich auf Java 10 springen, sobald alle Risiken besser verstanden werden.

Das zweite Problem betrifft die Entwickler der Bibliotheken. Ursprünglich wurde verkündet, dass Unsafe verschwinden würde. Das aber verfehlte den Punkt, dass in den meisten Fällen Unsafe nur aus Mangel an Alternativen genutzt wurde. Später wurde für Java 9 eine Alternative in Aussicht gestellt. Aber es hat sich gezeigt, dass diese Alternative zum Zeitpunkt, an dem der Java 9 Feature Freeze angesetzt war, nicht für alle Funktionalitäten bereit stehen würde.

In vielem Quellcode, der heute produktiv auf Maschinen läuft, kommt Unsafe zum Einsatz, weil es im Java-Ökosystem keine Alternative dafür gibt – man hätte sonst auf eine andere Sprache ausweichen müssen. In einigen Fällen hätte man zwar JNI und freigegebene DLLs und SOs für verschiedene Plattformen nutzen können. Der Gebrauch von JNI kann aber als größeres Risiko und als weniger sicher angesehen werden als die Verwendung einer zwar undokumentierten, aber weit verbreiteten Klasse.

Allerdings hätte JNI in vielen Fällen auch nicht so performen können wie es die intrinsischen Operationen in Unsafe tun. Das heißt, dass die „nativen“ Methoden mit einer oder mehreren Maschinen-Code-Anweisungen ersetzt werden, zum Beispiel sind intrinsische Unsafe-Operationen viel schneller für triviale Operationen als JNI.

Chris: JNI hat wegen der Übersetzung von Datentypen zwischen C und Java einen riesigen Overhead. Das war schon immer als Flaschenhals von JNI bekannt. Zudem sind Unsafe-Operationen, wie Peter sagt, intrinsisch, so dass der aktuelle C-Code niemals wirklich gebraucht wird und man nur direkten, nativen Speicher-Zugang erhält.

JAXenter: Ihr habt ein Vorschlagspapier für eine technische Lösungen veröffentlicht. Wie könnte eine solche aussehen?

Chris: Ich bin einer der Initiatoren des Google Doc, das diese große Diskussion angestoßen hat. Als Entwickler bei Hazelcast und auch persönlich mache ich mir Sorgen, was im Java-Ökosystem passieren wird, wenn sun.misc.Unsafe irgenwann einmal für immer verschwindet. Bis jetzt haben wir gehört, dass es in Java 9 einen Parameter in der Kommandozeile geben wird, um das versteckte sun.misc.Unsafe-Paket zurück zu holen. Aber wie lange wird dieser Parameter bleiben?

Im Moment bleiben nicht viele Alternativen oder, wie im Fall von VarHandles, scheinen diese die Probleme nicht vollständig zu lösen. Wir haben uns VarHandles letzte Woche auf der JCrete-Konferenz angesehen, und auch wenn sie Lösungen für einige Probleme anbieten, wie beispielsweise einen schnellen Array-Zugriff, gehen sie doch an vielen Punkten vorbei, für die sie eigentlich die Lösung darstellen sollen. Aber wir arbeiten derzeit mit den Entwicklern zusammen, um zumindest VarHandles für Java 9 richtig hinzukriegen.

Peter: Das Papier, das Chris aufgesetzt hat, hat die Aufmerksamkeit der richtigen Leute auf sich gezogen. Ich habe zuvor schon versucht, eine ähnliche Diskussion in Gang zu setzen, aber ohne Erfolg. Was ich in der Vergangenheit vorgeschlagen habe, ist eine Erweiterung des ByteBuffer APIs oder eines ähnlichen APIs. Die Projekte Chronicle und Aeron machen das beide, und so hatten wir einen Ersatz für Unsafe, der sich in der Produktion über Jahre hinweg bewährt hat.

Dadurch wird zwar nur ein Teil der Unsafe-Operationen abgedeckt. Aber es scheint ein natürlicherer Weg zu sein, um die Begrenzungen im API aufzuheben, als ein ganz neues API zu erfinden. Die Einführung von VarHandles fühlt sich für mich wie eine zu komplizierte Lösung für das an, was einfach eine einzige Maschinen-Anweisung für den Zugriff auf den Speicher ist. Ich freue mich darauf zu sehen, wie das für Off-Heap-Datenstrukturen funktioniert.

Chris: In diesem Fall stimme ich nicht ganz zu. Einerseits scheinen VarHandles vor allem von Implementierungsseite her extrem kompliziert zu sein, aber damit werden die meisten User ohnehin nichts zu tun haben. Andererseits mag ich das VarHandles API, denn es transformiert die unterschiedlichen Implementierungen von Buffern – momentan haben wir einen Array-bezogenen Buffer, einen Unsafe-bezogenen Buffer, einen ByteBuffer-bezogenen Buffer – in eine einzige, leichtgewichtige Wrapper-Implementierung über VarHandles, die (sofern sie richtig implementiert wird) einen einheitlichen Zugang zu allen verschiedenen Datenspeichern ermöglicht.

JAXenter: Ihr habt auch eine Working Group vorgeschlagen. Was erwartet ihr euch davon?

Chris: Die Working Group bildet sich gerade. Die Idee dabei ist, all das Wissen und Engagement zu bündeln, das momentan in der Java-Community verstreut ist.

Peter: Ich glaube, dass wir Anwendungsbeispiele aus der realen Welt zeigen müssen, damit die JVM-Designer herausfinden können, welcher der beste Weg ist, um Lösungen zu finden.

JAXenter: Ihr habt von VarHandles gesprochen. Könnt ihr die Idee dahinter vorstellen?

Chris: Wir waren letzte Woche auf der JCrete-Konferenz und hatten eine hitzige Diskussion über das Entfernen von Unsafe. Aufgrund der Diskussion beschäftige ich mich momentan intensiv mit den VarHandles-Prototypen und implementiere erste Tests, um herauszufinden, ob es wirklich wie versprochen Probleme lösen kann und ob die Geschwindigkeit stimmt. Bislang habe ich eine Hand voll Use Cases gefunden, die noch nicht abgedeckt sind. Ich arbeite mit Paul Sandoz daran, sie zu lösen. VarHandles sieht wie ein guter erster Schritt für ein Ersatz-API aus, allerdings wird es nur die Teile für den Memory-Zugang in sun.misc.Unsafe ersetzen. Es fehlen immer noch zahlreiche Funktionalitäten, die ersetzt werden müssen.

Peter: Unser wichtigster Use Case sind verteilte, persistente Off-Heap-Datenstrukturen. Der Vorteil ist, dass wir geteilte Daten zwischen Prozessen genauso schnell nutzen können wie geteilte Daten zwischen Threads. Wir können Daten auch in einer Signalfolge von 30 Millionen Updates pro Sekunde persistieren. Einer unserer Kunden schreibt 24 Millionen Marktdaten-Events pro Sekunde während der Hochzeiten auf dem Markt. Weil der Code Garbage-Collector-frei ist, geschieht das ohne Pausen. In der Vergangenheit hätte das nur mit C++ oder C erreicht werden können, aber Unsafe gibt uns die Performance von C, wo wir sie brauchen, mit der Portabilität und dem Entwicklungskomfort von Java.

Chris: Ja, da hat Peter Recht. VarHandles wird dieses Problem nicht beheben. Soweit ich sehen kann, wird das Projekt Panama eine Lösung dafür anbieten, aber das wird nicht vor Java 10 passieren. Insgesamt fühlt sich Java 9 irgendwie kaputt an, und, wie ich auch in der JCrete-Diskussion gesagt habe, sollten wir vielleicht darüber nachdenken: „Können wir Java 9 nicht einfach überspringen?“

Peter: Vielleicht wird Java 9 die Änderungen bringen, die wir brauchen, um die JVM-Plattform voran zu bringen. Aber aus Sicht der Endnutzer scheint das Release nicht so überzeugend zu sein wie Java 8, und ich kann mir vorstellen, dass eine große Prozentzahl von Usern Java 9 überspringen wird.

JAXenter: Chris, Peter, vielen Dank für dieses Interview.

Christoph Engelbert is the Technical Evangelist and Senior Solutions Architect at Hazelcast. He’s also an Apache Committer and Open Source enthusiast, and is mostly interested in Performance Optimizations and understanding the internals of the JVM and the Garbage Collector.


Peter Lawrey has the most Java answers on StackOverflow, is the founder of the Performance Java User’s Group with over 1000 members, and the lead developer of OpenHFT, open source software used by investment banks, trading houses, and hedge funds.

 

Aufmacherbild: Birthday-anniversary cake with red candles showing Nr. 9 von Shutterstock.com / Urheberrecht: Fernando Sanchez Cortes

Verwandte Themen:

Geschrieben von
Hartmut Schlosser
Hartmut Schlosser
Content-Stratege, IT-Redakteur, Storyteller – als Online-Teamlead bei S&S Media ist Hartmut Schlosser immer auf der Suche nach der Geschichte hinter der News. #java #eclipse #devops #machinelearning #seo. Zum Lächeln bringen ihn kreative Aktionen, die den Leser bewegen. @hschlosser
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
4000
  Subscribe  
Benachrichtige mich zu: