Veröffentlichung von Java SE 25 LTS und OpenJDK 25

Nach sechs Monaten Entwicklung hat die Firma Oracle die Plattform Java SE 25 (Java Platform, Standard Edition 24) veröffentlicht, deren Referenzimplementierung das Open-Source-Projekt OpenJDK nutzt. Abgesehen von der Entfernung einiger veralteter Funktionen wurde in Java SE 25 die Abwärtskompatibilität zu früheren Versionen der Java-Plattform beibehalten – die meisten zuvor geschriebenen Java-Projekte werden ohne Änderungen unter der neuen Version lauffähig sein. Installationsfertige Builds von Java SE 25 (JDK, JRE und Server JRE) sind für Linux (x86_64, AArch64), Windows (x86_64) und macOS (x86_64, AArch64) verfügbar. Die im Rahmen des OpenJDK-Projekts entwickelte Referenzimplementierung von Java SE 25 ist vollständig unter der GPLv2-Lizenz mit Ausnahmen der GNU ClassPath lizenziert, die das dynamische Binden an kommerzielle Produkte ermöglichen.

Java SE 25 gehört zu den Versionen mit erweitertem Support, für die Updates bis zum Jahr 2033 veröffentlicht werden (Open-Source-Updates erscheinen bis September 2030). Auch die LTS-Versionen Java SE 17 und 21 werden weiterhin unterstützt, mit Updates, die bis 2029 und 2031 veröffentlicht werden, respektive (Open-Source bis 2026 und 2028). Die erweiterte Unterstützung der LTS-Editionen Java SE 8 und 11 wird bis 2030 und 2032 dauern.

Unter den Neuerungen in Java SE 25 (1, 2, 3, 4):

  • Eine experimentelle API StableValue wurde hinzugefügt, um mit Objekten zu arbeiten, die unveränderliche Daten enthalten und in der JVM als Konstanten verarbeitet werden. Für solche Objekte gelten Leistungsoptimierungen, die den Feldern mit dem Schlüsselwort „final“ ähnlich sind. Die API StableValue trennt die Erstellung permanenter Werte von deren Initialisierung, garantiert, dass ein Wert nur einmal initialisiert werden kann, verkürzt die Programmstartzeiten und ermöglicht die Anwendung von Optimierungen zur Konstantenverdichtung (constant-folding) im Benutzer-Code, die zuvor nur im internen JDK-Code verwendet wurden. class Application { // War: // static final UserService USERS = new UserService(); // Ist: static final StableValue USERS = StableValue.of(); public static UserService users() { return USERS.orElseSet(UserService::new); } }
  • Eine experimentelle API zur Kodierung und Dekodierung von Objekten mit kryptographischen Schlüsseln, Zertifikaten und Widerrufsllisten wurde hinzugefügt, die das PEM-Format (Pivacy-Enhanced Mail) verwendet.
  • Unterstützung für Scoped Values wurde hinzugefügt, die es ermöglichen, unveränderliche Daten in Threads gemeinsam zu nutzen und effizient Daten zwischen untergeordneten Threads auszutauschen (Werte werden vererbt). Scoped Values entwickeln sich weiter, um den Mechanismus der Thread-lokalen Variablen zu ersetzen und sind bei der Verwendung einer sehr großen Anzahl virtueller Threads (tausende und Millionen von Threads) effizienter. Der Hauptunterschied zwischen Scoped Values und thread-lokalen Variablen besteht darin, dass erstere einmal geschrieben werden, danach nicht mehr geändert werden können und nur zur Laufzeit des Threads verfügbar bleiben.
  • Eine API zur Verwendung von kryptografischen Schlüsselableitungsfunktionen (KDF, key derivation function) wurde hinzugefügt, die es ermöglichen, zusätzliche Schlüssel der erforderlichen Länge auf der Grundlage eines geheimen Schlüssels (z. B. eines Passworts) und einer beliebigen Datensammlung zu generieren.
  • Der Code und die Build-Skripte zur Unterstützung von 32-Bit-x86-Systemen wurden entfernt. Die Abschaffung der Unterstützung für 32-Bit-x86-Systeme hat es ermöglicht, die Infrastruktur für das Build- und Testen des JDK zu vereinfachen und Funktionen zu implementieren, die auf Plattformen angewiesen sind, ohne Fallback-Handler für 32-Bit-x86-Systeme erstellen zu müssen.
  • Die Möglichkeit, einen Ausdruck „import module M“ zu verwenden, um alle von dem angegebenen Modul exportierten Pakete auf einmal zu importieren, wurde hinzugefügt. Diese Änderung vereinfacht die Wiederverwendung von Modullbibliotheken erheblich, da Bibliotheken und Klassen ohne Angabe ihres Standorts in der Pakethierarchie eingebunden werden können. Zum Beispiel führt die Angabe „import module java.base“ zum Import aller 54 Pakete, die im Modul java.base enthalten sind, die zuvor einzeln erwähnt werden mussten (z. B. „import java.io.*“, „import java.util.*“ usw.).
  • Eine kompakte Variante der Programmgestaltung wurde vorgeschlagen, die sich als nützlich für Schulungen und bei der Entwicklung kleiner Anwendungen erweisen kann. In kompakter Form ist keine Definition zusätzlicher Klassen erforderlich, typische APIs werden automatisch importiert und vereinfachte Ein-/Ausgabemethoden stehen zur Verfügung. Zum Beispiel kann die Anwendung „Hello, World!“ auf folgendes reduziert werden: void main() { IO.println(„Hello, World!“); }
  • Es ist zulässig, Ausdrücke in Konstruktoren vor dem Aufruf von super(…) anzugeben, der für den expliziten Aufruf des Konstruktors der Elternklasse aus dem Konstruktor der abgeleiteten Klasse verwendet wird, sofern diese Ausdrücke nicht auf die vom Konstruktor erstellte Instanz verweisen. class Outer { void hello() { System.out.println("Hallo"); } class Inner { Inner() { hello(); super(); } } }
  • Der generative Modus des Shenandoah-Garbage-Collectors wurde hinzugefügt, bei dem alte und neu erstellte Objekte getrennt verarbeitet werden, um die Effizienz der Bereinigung von Objekten mit kurzer Lebensdauer zu erhöhen. Der neue Modus sorgt für eine vorhersehbarere Durchsatzrate, Widerstandsfähigkeit gegenüber Laständerungen und eine Reduktion des Speicherverbrauchs beim Garbage-Collection. Der Shenandoah-Planer zielt darauf ab, die Stop-Zeit während der Garbage-Collection zu reduzieren, indem er einen größeren Arbeitsumfang parallel zur Ausführung von Java-Anwendungen durchführt.
  • Die Erstellung eines Caches für die vorab (Ahead-of-Time) Lade- und Zusammenstellung von Klassen wurde vereinfacht, wodurch der Start der HotSpot-JVM beschleunigt wird, indem Klassen in bereits geladenem und zusammengestelltem Zustand verwendet werden. Beim Start sind keine separaten Operationen zur Protokollierung von Aktivitäten und zur Erstellung eines Caches mehr erforderlich, sondern es genügt ein Befehl: java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App …
  • Bei der Start der HotSpot-Java-VM wurde die Möglichkeit implementiert, Ausführungsprofile von Methoden zu verwenden, die beim vorherigen Start der Anwendung ermittelt wurden. Diese Änderung ermöglicht es dem JIT-Compiler, auf die Sammlung von Statistiken zu verzichten und sofort damit zu beginnen, nativen Code zu generieren, ohne auf die Erstellung des Profils warten zu müssen.
  • In der HotSpot-JVM wurde die Unterstützung für kompakte Objektheader implementiert, deren Größe unter 64-Bit-Systemen von 96 auf 64 Bit (von 12 auf 8 Byte) reduziert wurde. Die Verkleinerung der Header-Größe ermöglicht eine Reduzierung der Heap-Größe und steigert die Effizienz des Caches.
  • Es wurde eine Testimplementierung der Vector-API vorgeschlagen, die Funktionen für Vektorcomputing bereitstellt, die unter Verwendung von Vektoranweisungen der Prozessoren x86_64 und AArch64 ausgeführt werden und es ermöglichen, Operationen gleichzeitig auf mehrere Werte (SIMD) anzuwenden. Im Gegensatz zu den im JIT-Compiler HotSpot angebotenen Möglichkeiten zur automatischen Vektorierung von Skalarkoperationen bietet die neue API die Möglichkeit, die Vektorisierung explizit für die parallele Datenverarbeitung zu steuern.
  • Für Tests wurde die fünfte Vorabversion der API für strukturierten Parallelismus (Structured Concurrency) vorgeschlagen, die die Entwicklung multithreaded Anwendungen erleichtert, indem mehrere Aufgaben, die in verschiedenen Threads ausgeführt werden, als ein einzelner Block bearbeitet werden.
  • Im Mechanismus des Musters wurde der dritte Vorabentwurf für die Nutzung primitiver Typen (int, byte, char und andere Basisdatentypen, die keine Objekte sind) in allen Arten von Vorlagen, im Operator „instanceof“ und in „switch“-Blöcken vorgeschlagen. switch (x.getStatus()) { case 0 -> „okay“; case 1 -> „warnung“; case 2 -> „fehler“; case int i -> „unbekannter Status: “ + i; } if (i instanceof byte b) { … b … }
  • Im JDK Flight Recorder (JFR) wurde experimentelle Unterstützung für Profiling mit genauerer Verfolgung der CPU-Ressourcennutzung auf der Linux-Plattform hinzugefügt. Die Ausführungszeit verschiedener Konstruktionen kann anschaulich mit farblichen „FlameGraph“-Diagrammen visualisiert werden.
  • Die Stabilität des JDK Flight Recorder (JFR) wurde beim asynchronen Sampling von Java-Thread-Stacks verbessert, indem der Aufrufstapel nur durch „sichere Punkte“ (safepoints) umgangen wird.
  • Im JDK Flight Recorder (JFR) wurden Werkzeuge zur Rückverfolgung und Bewertung der Ausführungszeit von Methoden hinzugefügt. Die Rückverfolgung des Aufrufstapels spezifischer Methoden und die Erfassung präziser Statistiken über Methodenaufrufe, einschließlich Metriken wie Ausführungszeit und Anzahl der Aufrufe, werden unterstützt.

Quelle: opennet.ru

60GB SSD 8Gb DDR4