Java 13 Überblick

Der neue Release-Zyklus der Java Releases ist jetzt in vollem Schwung, so kündigt sich bereits das nächste Release an. Java 13 ist jetzt da und bringt einige Neuerungen mit. Vorwiegend umfassen die neuen Features Erweiterungen oder Korrekturen der bereits in Java 12 enthaltenen Features. Über Java 12 Features haben wir hier bereits ausführlich berichtet.

Dynamic CDS Archives

Bereits in Java 5 wurde Class-Data-Sharing (CDS) eingeführt. Bis Java 10 waren die geteilten Archive jedoch nur für den Bootstrap-Classloader zugänglich. CDS trägt zur Verringerung der Startzeiten von Java-Anwendungen bei, indem bestimmte Informationen über Klassen in sogenannten Class-Data-Sharing-Archives mit abgelegt werden. Diese Daten können dann zur Laufzeit geladen und auch von mehreren JVMs benutzt werden. Mit Java 10 wurde CDS um Application-Class-Data-Sharing (AppCDS) erweitert. AppCDS ermöglicht es auch dem eingebauten System-Classloader, dem eingebauten Platform-Classloader und benutzerdefinierten Classloadern, auf die CDS-Archive zuzugreifen. Zum Anlegen der CDS-Archive werden Klassenlisten benötigt, um die zu ladenden Klassen identifizieren zu können. Bisher mussten diese Klassenlisten durch Probeläufe der Anwendung ermittelt werden, um festzustellen welche Klassen während der Ausführung tatsächlich geladen werden. Seit Java 12 werden Default-CDS-Archives standardmäßig mit dem JDK ausgeliefert. Diese basieren auf einer Default-Klassenliste des JDK.

Dynamic-CDS-Archives bauen nun auf dieser Basis auf. Ziel ist es, sich die zusätzlichen Probeläufe der Anwendung zu sparen. Nach der Ausführung einer Anwendung werden die neu geladenen Anwendungs- und Bibliotheksklassen, die nicht bereits im Default- / Base-Layer-CDS enthalten sind, archiviert. Aktiviert wird das dynamische Archivieren per CLI. In einer zukünftigen Erweiterung des Features könnte das Archivieren der Klassen vollständig automatisch und transparent ablaufen. Für mehr Details, siehe JEP 350.

ZGC gibt ungenutzten Speicher nun auch schneller frei

Der Z-Garbage-Collector (ZGC) gibt derzeit den für die Anwendung reservierten Heap Speicher nicht wieder frei. Das führt dazu, dass Anwendungen über ihre Lebensspanne hinweg für gewöhnlich weit mehr Speicher verbrauchen, als dies notwendig wäre. Dieses Verhalten ist in beinahe allen Fällen unvorteilhaft. Anwendungen, die in ressourcenarmen Umgebungen ausgeführt werden, sind beispielsweise besonders davon betroffen. Andere Garbage-Collectoren wie der G1 und Shanandoah unterstützen bereits das Freigeben von ungenutztem Speicher.

ZGC unterteilt den Heap in Z-Pages. Leere Z-Pages werden nach dem Collecten im Z-Page-Cache abgelegt, um sie später zur Neuzuweisung wiederzuverwenden. Der Cache ist ein Key-Performance-Feature des ZGC, da das Zuweisen und Freigeben von neuen Z-Pages kostenintensiv ist. Der Cache repräsentiert folglich bereits eine Liste des beanspruchten, aber ungenutzten Speichers. Mit Java 13 soll eine Z-Page im Cache nun nach einem simplen Timeout wieder freigegeben werden. Der Timeout-Value kann per CLI überschrieben werden. In zukünftigen Iterationen könnten verfeinerte Entscheidungsmechanismen eingeführt werden. Für mehr Details, siehe JEP 353.

Socket APIs werden überarbeitet

Die java.net.Socket und java.net.ServerSocket APIs und deren zugrunde liegende Implementationen sind Überbleibsel aus dem JDK 1.0. Zu großen Teilen bestehen sie aus legacy Java- und C-Code, was die Wartbarkeit und Erweiterbarkeit deutlich erschwert. Die NioSocketImpl soll die veraltete PlainSocketImpl nun ablösen. NioSocketImpl ist an die bereits vorhandene New I/O Implementierung angelehnt und benutzt dessen vorhandene Infrastruktur im JDK mit, was Wartbarkeit und Debugging vereinfacht. Grund dafür, dass diese Änderungen genau jetzt angegangen werden ist, dass die aktuellen Implementationen nicht kompatibel mit geplanten zukünftigen Erweiterungen der Sprache sind. Beispielsweise behinderten einige Concurrency-Probleme den zukünftigen Einsatz von leichtgewichtigen User-Threads (geplant unter dem Namen Project Loom). Für mehr Details, siehe JEP 353.

Switch Expressions wurden leicht angepasst

Die Switch Expressions sollen eine Alternative zu den komplexen und fehleranfälligen Switch Statements bieten. Es wird argumentiert, dass in vielerlei Fällen eine Expression eine nativere Ausdrucksweise darstellt. Switch Expressions gibt es als Preview-Feature bereits seit Java 12. Adressierte Aspekte sind der fehlende Scope, unbeabsichtigter Fallthrough, Boilerplate-Code und nicht garantierte Fallabdeckung. Eine ausführliche Übersicht über die Eigenschaften wurde bereits in einem vergangenen Blog-Post spezifisch zum Thema Switch Expressions in Java 12 gegeben.

Nachdem das Feature nach der ersten Iteration seit Java 12 einiges an Feedback bekommen hat, wurde sich nun dazu entschlossen das break with value statement zugunsten eines yield-Statements zu entfernen. Grund für diese Entscheidung war die bessere Differenzierbarkeit zwischen Switch-Statement und Switch-Expression. yield kann nur innerhalb einer Expression benutzt werden, während break nur für Statements zulässig ist. Switch-Expressions verbleiben vorerst noch als Preview-Feature.

Nachfolgend sind noch zwei Codebeispiele zum direkten Vergleich zu sehen. Dabei wurde die Expression-Syntax mit den wenigsten Abweichungen vom traditionellen Statement benutzt, um die Unterscheidung durch yield besser hervorzuheben. Für mehr Details, siehe JEP 354.

// Switch-Statement mit break
private static String statementMultilabel(int switchArg){
     String str = "not set";
     switch (switchArg){
         case 1,2:
             str = "one or two";
             break;
         case 3:
             str = "three";
             break;
     };
     return str;
}
// Switch-Statement mit yield
private static String expressionBreakWithValue(int switchArg){
     return switch (switchArg){
         case 1, 2: yield "one or two";
         case 3: yield "three";
         default: yield "smaller than one or bigger than three";
     };
}

Raw String Literals kommen als Text Blocks

Ebenfalls seit Java 12 im Gespräch (jedoch damals verschoben) sind die Raw-String-Literals. Eine Variante dieser soll nun als Preview-Feature mit dem Namen Text Blocks ins JDK 13. Auch über die Raw-String-Literals haben wir bereits in einem gesonderten Beitrag zu Raw-String-Literals ausgiebig berichtet.

In vielen Anwendungen werden Strings bestehend aus mehrzeiligen Texten oder Codeschnipsel aus anderen Sprachen wie HTML oder SQL verarbeitet. Kernidee der RSL ist es, Strings die mehrere Zeilen umfassen so menschenlesbar wie möglich zu machen. Sprich den für gewöhnlich notwendigen exzessiven Gebrauch an Escapes und Java-spezifischen Formatierungen einzudämmen. So sollten beispielsweise Zeichen wie \n für mehrzeilige Strings überflüssig werden.

Nach ausgiebigem Feedback zum ersten Vorschlag der RSL, hat man sich nun zum einen dazu entschlossen, als Indikatoren für Start und Ende der Text Blöcke dreifache Anführungszeichen zu verwenden. Die öffnenden, aber nicht die schließenden Anführungszeichen müssen dabei in ihrer Zeile alleine stehen. Textblöcke können überall benutzt werden, wo auch reguläre String-Literale benutzt werden könnten.

Nachfolgend sind noch zwei Codebeispiele zum direkten Vergleich zu sehen. Ersteres zeigt ein einfaches HTML-Schnipsel, wie man es heute in einer Anwendung finden würde. Zweiteres zeigt selbiges Schnipsel als Text-Block. Für mehr Details, siehe JEP 355.

// Ohne Text Blocks
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, Escapes</p>\n" +
              "    </body>\n" +
              "</html>\n";
// Mit Text Blocks
String html = """
              <html>
                  <body>
                      <p>Hello, Text Blocks</p>
                  </body>
              </html>
              """;

Das ist schon über Java 14 bekannt…

Java 14 ist noch ein halbes Jahr entfernt. Dennoch im Folgenden schon mal eine kleine Aussicht über das Wenige, das bereits zum kommenden Release bekannt ist und über was man munkelt.

Offiziell angestrebt für Java 14 wird aktuell nur JEP 352: Non-Volatile Mapped Byte Buffers. MappedByteBuffer soll demnach in Zukunft auch auf persistenten Speicher (Non-Volatile) zugreifen und somit Daten auch dauerhaft speichern können.

Weiterhin spekuliert wird, dass auch ein neues Packaging-Tool Teil vom JDK 14 sein wird. Seitdem JavaFX mit Java 12 aus dem JDK entfernt wurde, entfiel auch das viel verwendete Packaging-Tool javapackager, welches das komfortable Verpacken von Java-Anwendungen in beispielsweise .exe Formaten ermöglichte. Um diesen Verlust auszugleichen, wird nun unter JEP 343: Packaging Tool an einem neuen Tool namens jpackage gearbeitet.

Short URL for this post: https://wp.me/p4nxik-3vk
This entry was posted in Java Basics and tagged , . Bookmark the permalink.

Leave a Reply