Aus Linux-Magazin 06/2025

Java 24 wird kompakter und schneller

© stockee / 123RF.com

Anfang März 2025 erschien das neue Feature Release Java 24 mit einer Rekordzahl an Änderungen. Wir stellen Ihnen die wichtigsten vor und präsentieren einige weitere Neuigkeiten aus dem Java-Umfeld.

Seit Anfang März steht als neuestes Feature Release Java 24 [1] bereit. Mit 25 umgesetzten Änderungen [2] aus JDK Enhancement Proposals (JEPs) stellt es einen Rekord auf – in der Regel bearbeiten die Entwickler nur ein Dutzend JEPs. Hinzu kommen gut 60 Bugfixes und kleinere Änderungen, die Java weiter relevant und attraktiv halten. Immerhin hält es sich seit über 20 Jahren solide unter den beliebtesten Programmiersprachen, was eine gute Balance zwischen Spracherneuerungen und Rückwärtskompatibilität erfordert.

Allerdings ist uneingeschränkte Rückwärtskompatibilität nicht mehr das Ziel: Auch bei Java entfallen zunehmend veraltete Features oder Portierungen. So stellen die Entwickler mit Java 24 die Unterstützung für 32-Bit-PCs unter Windows (JEP 479) und Linux (JEP 501) ein. Viel Protest dürfte das nicht hervorrufen: Neue 32-Bit-x86-CPUs werden nicht mehr hergestellt, Bestandssysteme können nach wie vor ältere Java-Versionen nutzen. Ganz vorüber ist die 32-Bit-Ära jedoch noch nicht: Den unter anderem auf dem Raspberry Pi genutzten 32-Bit-ARM-Port pflegen die Entwickler weiter.

Auch dem SecurityManager geht es endgültig an den Kragen (JEP 486). Er gilt seit 2021 als deprecated und wird sieben Java-Versionen später nun entfernt. Ein ähnlicher Prozess beginnt für »sun.misc.Unsafe« (JEP 498) und JNI (JEP 472). Beide ermöglichen direkten Speicherzugriff und umgehen damit potenziell das Speichermanagement von Java. Vor dem Zugriff auf natives Memory, das erstaunlich viele Bibliotheken noch unter der Haube nutzen, wird jetzt beim Start gewarnt. Ganz vermeiden lässt sich das wohl nicht: So verwendet die beliebte GUI-Bibliothek JavaFX native GTK-Libraries für Oberflächen. Solange niemand die Implementierung komplett umstellt, wird man mit einer Warnung wie in Abbildung 1 leben müssen.

Abbildung 1: Java 24 warnt vor der Verwendung von JNI und »sun.misc.Unsafe«.

Abbildung 1: Java 24 warnt vor der Verwendung von JNI und »sun.misc.Unsafe«.

Experimentell

Ganz am Anfang ihres Lebenszyklus befinden sich hingegen die neuen, experimentellen Features in Java 24. Die Compact Object Header (JEP 450) versprechen, den Speicherverbrauch aller Java-Anwendungen zu reduzieren. Aktuell startet der Speicher jedes Java-Objekt mit einer 96 bis 128 Bit langen Referenz auf seine Klasse. JEP 450 reduziert sie auf 64 Bit. Mit der Option »-XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders« lässt sich das neue Feature einschalten, das ohne weitere Änderungen 10 bis 20 Prozent weniger Speicherverbrauch nach sich ziehen soll. Das bestätigt sich in unseren Tests schon bei kleineren Anwendungen.

Wer den von Red Hat entwickelten Shenandoah Garbage Collector einsetzt, kann sich über den mit JEP 404 eingeführten Generational Mode freuen. Er konzentriert sich wie bei den anderen Garbage-Kollektoren vor allem auf frisch erzeugte Objekte, wo die Wahrscheinlichkeit besonders hoch liegt, ungenutzte Objekte zu finden. Für den ZGC Garbage Collector gibt es das Feature schon länger, der Non-Generational Mode wurde in Java 24 sogar komplett entfernt (JEP 490). Auch an den Standard-Garbage-Collector G1 legten die Entwickler Hand an, um sowohl das Zusammenspiel mit dem JIT Compiler zu verbessern als auch den Code für die JVM-Entwickler verständlicher zu machen (JEP 475). Einen guten Einblick in das Thema gibt übrigens ein von Stefan Johansson auf der Devoxx gehaltener Vortrag [3].

Etwas ausgereifter sind die Features im Preview Status. Dazu gehören unter anderem die Arbeiten an Post-Quantum-Verschlüsselungsverfahren. Die FIPS-204-Signatur wurde von der NIST als quantensicheres Verfahren spezifiziert, JEP 496 und JEP 497 implementiert Teile davon. Dazu kommt die neue Key Derivation Function API (JEP 478). Mit ihr lassen sich sichere Schlüssel auf Basis von anderen Schlüsseln und Zufallsdaten erstellen. Damit können Java-Server und -Clients weitere sichere Verschlüsselungen nutzen, bevor Quantum Computing eine ernsthafte Bedrohung auf dem Transport-Layer darstellt.

Project Amber

Kleinere Änderungen der Sprachsyntax stehen im Fokus des Projekts Amber [4]. Die ersten beiden in Java 24 vereinfachen den schnellen Code zwischendurch. Mit der Jsh steht seit Java 9 ein Interpreter bereit, der Java-Code ohne vorheriges Kompilieren auf der Kommandozeile startet. Dem einfachen Scripting stand bisher die umfangreiche Java-Syntax entgegen – wer möchte sich beim Scripting schon mit allen Importen, Klassendefinition und einer Main-Methode für ein “Hello World” herumschlagen?

Mit den JEPs 495 (Single Source Files) und 494 (Module Import) lässt sich diese Schreibarbeit sparen. Das Beispiel aus Listing 1 zeigt ein einfaches Script, das eine Eingabedatei abfragt (Zeile 5), deren Existenz prüft (Zeile 8), die ganze Datei einliest (Zeile 14) und dann die Anzahl der enthaltenen Wörter ohne Dubletten zählt. Das Ergebnis wird in einem Dialog (Abbildung 2) ausgegeben, vor allem, um die Module-Importe in Zeile 1 zu demonstrieren.

Abbildung 2: Einmal durchgez&auml;hlt: Der Code aus <a href="#artRef-l1">Listing&nbsp;1</a> auf sich selbst angewendet.

Abbildung 2: Einmal durchgezählt: Der Code aus Listing 1 auf sich selbst angewendet.

Dank der beiden JEPs kommt das Skript ohne vollständige Klassendeklaration und mit nur einer Zeile zum Importieren von Swing aus. Die ebenso aus Project Amber stammenden flexiblen Constructor Bodies (JEP 492) und Primitive in »instanceof« (JEP 488) wurden mit Java 23 erstmals vorgestellt. Sie haben in Java 24 keine Änderungen an der API erfahren, deshalb gilt nach wie vor unsere Beschreibung aus LM 11/2024 [5].

Listing 1

Record Patterns, Pattern Matching, Unnamed Patterns

import module java.desktop;
void main() throws Exception {
 // Eingabe, Ausgabe von Kommandozeilenargumenten
 while(true) {
 var eingabe = readln("Eingabedatei: ");
 if(eingabe.isEmpty())
 System.exit(0);
 var path = Paths.get(eingabe);
 if (!path.toFile().isFile()) {
 println("Datei nicht gefunden: " + eingabe);
 continue;
 }
 var uniqueWords = new HashSet<String>();
 Files.readString(path).lines().forEach(zeile -> uniqueWords.addAll(Arrays.asList(zeile.split("\\s+"))));
 JOptionPane.showMessageDialog(null, "Anzahl der einzigartigen Wörter: " + uniqueWords.size());
 }
}

TIPP

Codebeispiele zu den in diesem Artikel beschriebenen neuen Features in Java 24 stellt der Autor in seinem Repository auf Github [12] zur Verfügung.

Project Loom

Im Projekt Loom [6] geht es um die Verbesserung von Javas Multithreading-Fähigkeiten. Die großen Plattform-Provider betreiben inzwischen über 100 Millionen Concurrent Connections, die Senderaten für Messages liegen jenseits der 100 kHz. Das mit einer erschwinglichen Infrastruktur wartbar umzusetzen, stellt eine echte Herausforderung dar. Mit Java 21 wurden virtuelle Threads eingeführt, um Klimmzüge wie Thread Pools oder Reactive Programming überflüssig zu machen.

Java 24 nimmt nun weitere Detailverbesserungen vor. Im vierten und hoffentlich letzten Preview liegen Structured Concurrency (JEP 499) und Scoped Values (JEP 487) vor. Beim ersten JEP geht es darum, logisch zusammenhängenden, parallel ablaufenden Code leserlich und robust zu strukturieren. Das haben wir bereits in LM 05/2024 [7] vorgestellt, seitdem gab es keine Änderungen an der API. Ähnliches gilt für die Scoped Values, mit denen sich Thread-spezifische Variablen abbilden lassen. Im vorliegenden vierten Preview haben die Entwickler die API etwas verschlankt, ansonsten gilt auch hier das Beispiel aus LM 05/2024.

Jeder virtuelle Thread stützt sich letztlich auf einen Plattform-Thread, den nativ das Betriebssystem bereitstellt. Mit den virtuellen Threads kümmert sich Java selbst darum, einen virtuellen auf einen nativen Thread zu mounten respektive zu unmounten – hier gilt die gleiche Begrifflichkeit wie bei einem Dateisystem. Das Einhängen erfolgt, sobald ein nativer Thread frei ist, das Unmounten, sobald er beispielsweise auf einen Festplatten- oder Netzzugriff warten muss. Quelltext mit klassischen Thread-Steuerungsmechanismen wie »synchronized« oder »Object.wait()« führte bisher zum Pinning, also dem Anheften des virtuellen Threads an den nativen Thread. Dank JEP 491 geschieht das nicht mehr, sodass ungeänderter Code die Vorzüge von virtuellen Threads nutzen kann.

Zugeschnitten

Die meisten Entwickler verwenden die Java-Laufzeitumgebung ohne weitere Anpassungen. Es gibt jedoch gute Gründe, die Runtime exakt an die eigenen Anforderungen anzupassen: Das spart Plattenplatz, Bandbreite beim Verteilen und Startzeit. Mit JEP 493 wird die Erstellung dieser Java Images noch einfacher.

Listing 2 demonstriert die Schritte, um manuell ein minimales Java zu erstellen. Die erste Zeile stellt die Variable »JAVA_HOME« auf die richtige Version ein, hier enthält sie den Pfad zu Java 24. Als Nächstes kompilieren Zeile 2 und 3 die Quellen – das entspricht einem »mvn compile«. Anschließend wird mit Jlink ein neues Java-Image angelegt, das nur das benötigte Modul »java.desktop« und die Anwendung enthält (siehe Listing 3).

Im Verzeichnis »BeispielAnwendung/« findet sich eine neue Java-Runtime, die nur noch diese beiden Module enthält. Das normale JDK mit allen Werkzeugen, Bibliotheken, Lizenztexten und so weiter belegt gut 350 MByte Plattenplatz, die angepasste Version lediglich noch 90 MByte. Zum Starten der Anwendung braucht man wie in Zeile 5 nur noch Anwendungsmodule und -Klassen anzugeben, der »$CLASSPATH« kann entfallen.

Mit dem JEP 493 kann man so das Installationspaket aus Java und der Anwendung signifikant verschlanken, ohne den Code selbst anfassen zu müssen. Die Beispielanwendung der Oberflächenbibliothek AtlantaFX [8] zeigt das in der Praxis (Abbildung 3). Aus dem Maven-Lauf resultiert eine angepasste und in den Anwendungsnamen umbenannte Java-Version, was erspart, aufwendig Shell-Skripte und so weiter erstellen zu müssen.

Abbildung 3: AtlantaFX bietet zus&auml;tzliche Themes und Widgets f&uuml;r JavaFX.

Abbildung 3: AtlantaFX bietet zusätzliche Themes und Widgets für JavaFX.

Listing 2

Erzeugen einer minimalen JRE

$ export JAVA_HOME= Pfad/zu/Java24
$ $JAVA_HOME/bin/javac --enable-preview -source 24 -d module src/main/java/module-info.java
$ $JAVA_HOME/bin/javac --enable-preview -source 24 -d module src/main/java/de/groygroy/linuxmagazin/java24/BeispielAnwendung.java
$ $JAVA_HOME/bin/jlink --module-path  module --add-modules  java.desktop,Java24LM --output BeispielAnwendung
$ BeispielAnwendung/bin/java --enable-preview --module Java24LM/de.groygroy.linuxmagazin.java24.BeispielAnwendung

Listing 3

module-info.java

module Java24LM {
  requires java.desktop;
}

Project Leyden

Das Projekt Leyden [9] möchte Java-Anwendungen schneller starten. Als Namenspatron dient die Leidener Flasche, eine Frühform des Kondensators, mit der im 18. Jahrhundert als Kuriosum künstliche Blitze erzeugt wurden. Beim Start jeder Anwendung wird der Bytecode zuerst geladen, dann untersucht und gelinkt, bevor er ausgeführt wird. Das JEP 483 ermöglicht es nun, die gesammelten Informationen bei späteren Läufen wiederzuverwenden und verspricht so eine Reduktion der Startzeit um bis zu 30 Prozent.

Listing 4 zeigt die in Java 24 notwendigen Schritte. Im Lerndurchlauf mit dem AOT-Mode »record« (erste Zeile) startet man die Anwendung wie üblich, die dabei gesammelten Informationen landen in einer Datei (hier: »app.aotconf«). Ein zweiter Durchlauf mit dem AOT-Mode »create« erstellt auf Basis dieser Informationen den AOT-Cache, den die dritte Zeile beim Start mit übergibt. Dadurch kann Java auf die erneute Untersuchung der Klassen verzichten. Eine Testanwendung mit einem 2000 Klassen großen Datenmodell startete dadurch in unserem Text um 25 Prozent schneller.

Listing 4

Anwendung mit AOT

$ java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -cp ... de.cadoculus.SpeedTest
$ java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -cp ... de.cadoculus.SpeedTest
$ java -XX:AOTCache=app.aot -cp ... de.cadoculus.SpeedTest

Das Thema Ahead-of-time-Compilation ist im Java-Umfeld nicht komplett neu, die GraalVM beherrscht das schon eine ganze Weile. Dort verwendet man aber eher die Konzepte eines C-Compilers und greift tief in die Java-VM ein. JEP 483 fällt sehr viel leichtgewichtiger aus und lässt sich ab sofort ohne spezielle VMs oder eine Freigabe von Preview-Features nutzen.

Auch die seit Java 22 entwickelten Stream-Gatherers (JEP 485) und das Class-File API (JEP 484) haben den Preview-Status verlassen. Mit den Stream-Gatherers lassen sich Java-Streams um beliebige eigene Funktionen erweitern; seit der Vorstellung in LM 05/2024 haben sich daran keine Änderungen ergeben.

Die Class-File API ermöglicht über eine mitgelieferte API den direkten Zugriff auf Java-Bytecode. In der Vergangenheit erfolgte das über separate Bibliotheken wie ASM oder BCEL, die teilweise Monate für die Anpassung an die aktuellste Java-Version benötigten. Bytecode-Manipulation ist das Problem weniger Java-Entwickler, die damit erstellten Werkzeuge sollten dank JEP 484 beim Erscheinen neuer Java-Versionen schneller auch für Normalprogrammierer verfügbar sein.

Greifbar

Wer sich für die weitere Zukunft von Java interessiert, sollte sich den Devoxx-Vortrag von Brian Goetz über das Project Valhalla [10] auf Youtube ansehen. 30 Jahre nach der Erfindung von Java schlagen wir uns immer noch mit einem lobotomierten Speichermodell aus Primitiven und Objekten herum. Ursprünglich wurde es aus Performance-Gründen gewählt. Die nach 10 Jahren Entwicklung definierten Value Classes (JEP 401) sollen die dadurch entstandenen Probleme künftig elegant lösen. Allerdings fehlt dazu jeder greifbare Zeitplan. Näher an der Praxis bewegt sich Almas Baim, der in seinen Videos [11] zeigt, wie sich Shader aus JavaFX-Anwendungen heraus nutzen lassen.

Immerhin greifen die neuen Features aus Java 24 sofort: Schnellerer Start, weniger Speicherverbrauch, mehr Funktionalität – so gut wie jeder Entwickler findet hier Verbesserungen, die er sofort nutzen kann. Selbst die derzeit noch als Preview markierten Features arbeiten bereits so stabil, dass sie wohl mit der nächsten Langzeitversion im Herbst freigegeben werden. (jlu)

Der Autor

Carsten Zerbst erstellt mit seinem Team Software für Ingenieure, vom einfachen Konverter bis hin zur unternehmenskritischen Integrationslösung. Er sucht noch Teammitglieder in Hamburg und bietet interessante Abschlussarbeiten für Informatik- und Schiffbaustudierende an.

Infos

  1. OpenJDK 24: https://openjdk.org/projects/jdk/24/
  2. Release Notes: https://jdk.java.net/24/release-notes
  3. “Garbage Collection in Java: The progress since JDK 8”: https://www.youtube.com/watch?v=5wkzEy_BXdA
  4. Project Amber: https://openjdk.org/projects/amber
  5. Java 23: Carsten Zerbst, “Ereigniskarte”, LM 11/2024, S. 78, https://www.lm-online.de/50077
  6. Project Loom: https://openjdk.org/projects/loom
  7. Java 22: Carsten Zerbst, “Aufregend neu”, LM 05/2024, S. 81, https://www.lm-online.de/50601
  8. AtlantaFX: https://github.com/mkpaz/atlantafx
  9. Project Leyden: https://openjdk.org/projects/leyden
  10. Project Valhalla: https://www.youtube.com/watch?v=Dhn-JgZaBWo
  11. Almas Baim: https://www.youtube.com/watch?v=VLMHkyRXjxI&t=5s
  12. Beispiele: https://github.com/skfcz/Java24
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben