JDK 16: Die neuen Funktionen in Java 16

Das Java Development Kit (JDK) 16 hat seine anfängliche Rampdown-Phase erreicht, was bedeutet, dass der Funktionsumfang ab dem 10. Dezember 2020 eingefroren ist. Die neuen Funktionen in JDK 16 reichen von einer zweiten Vorschau versiegelter Klassen über Mustervergleich bis hin zu gleichzeitigem Thread- Stapelverarbeitung für die Speicherbereinigung.

JDK 16 wird die Referenzimplementierung der Version von Standard-Java sein, die JDK 15 folgen soll und am 15. September eintraf. Nach einem vorgeschlagenen Release-Zeitplan erreicht JDK 16 am 14. Januar 2021 eine zweite Rampdown-Phase, gefolgt von Release-Kandidaten, die am 4. und 20. Februar eintreffen 18. Februar 2021. Die Produktionsfreigabe soll am 16. März 2021 veröffentlicht werden.

17 Vorschläge zielen offiziell auf JDK 16 ab dem 10. Dezember 2020 ab. Zu den neuen Funktionen von Java 16 gehören:

  • Der Warnungsvorschlag für wertbasierte Klassen kennzeichnet die primitiven Wrapper-Klassen als wertbasiert und veraltet ihre Konstruktoren zum Entfernen, was zu neuen Verfallswarnungen führt. Es werden Warnungen vor nicht ordnungsgemäßen Synchronisierungsversuchen für Instanzen wertbasierter Klassen in der Java-Plattform ausgegeben. Diese Bemühungen werden vom Valhalla-Projekt vorangetrieben, das das Java-Programmiermodell in Form primitiver Klassen erheblich verbessert. Primitive Klassen deklarieren Instanzen als identitätsfrei und können Inline- oder reduzierte Darstellungen ausführen, wobei Instanzen frei zwischen Speicherorten kopiert und unter Verwendung der Werte von Instanzfeldern codiert werden können.Das Design und die Implementierung primitiver Klassen in Java sind jetzt so ausgereift, dass die Migration bestimmter Klassen der Java-Plattform zu primitiven Klassen in einer zukünftigen Version erwartet werden kann. Kandidaten für die Migration werden in API-Spezifikationen informell als wertbasierte Klassen bezeichnet.
  • In JDK 15, das zuvor in der Vorschau angezeigt wurde, beschränken versiegelte Klassen und Schnittstellen, welche anderen Klassen und Schnittstellen sie erweitern oder implementieren können. Zu den Zielen des Plans gehört es, dem Autor einer Klasse oder Schnittstelle zu ermöglichen, den für die Implementierung verantwortlichen Code zu steuern, eine deklarativere Möglichkeit als Zugriffsmodifikatoren bereitzustellen, um die Verwendung einer Oberklasse einzuschränken, und zukünftige Anweisungen beim Mustervergleich zu unterstützen, indem eine Grundlage für bereitgestellt wird Analyse von Mustern.
  • Standardmäßig starke Kapselung von JDK-Interna, mit Ausnahme kritischer interner APIs wie z misc.Unsafe. Benutzer können die entspannte, starke Kapselung auswählen, die seit JDK 9 die Standardeinstellung ist. Zu den Zielen dieses Vorschlags gehören die Verbesserung der Sicherheit und Wartbarkeit des JDK als Teil von Project Jigsaw und die Ermutigung der Entwickler, von der Verwendung interner Elemente zur Verwendung von Standard-APIs zu migrieren dass sowohl Entwickler als auch Endbenutzer problemlos auf zukünftige Java-Versionen aktualisieren können. Dieser Vorschlag birgt das Hauptrisiko, dass vorhandener Java-Code nicht ausgeführt werden kann. Entwickler werden aufgefordert, das jdeps-Tool zu verwenden, um Code zu identifizieren, der von internen Elementen des JDK abhängt, und auf Standardersatz zu wechseln, sofern verfügbar. Entwickler können eine vorhandene Version wie JDK 11 verwenden, um vorhandenen Code mithilfe von zu testen --illegal-access=warnum interne Elemente zu identifizieren, --illegal-access=debugauf die über Reflexion zugegriffen wird,  um fehlerhaften Code zu lokalisieren und mit zu testen --illegal-access=deny.
  • Fremdlinker-API, die statisch typisierten, reinen Java-Zugriff auf nativen Code bietet. Diese API befindet sich in JDK 16 in einer Inkubatorphase. Zusammen mit der vorgeschlagenen Fremdspeicher-Zugriffs-API vereinfacht die Fremdlinker-API den ansonsten fehleranfälligen Prozess der Bindung an eine native Bibliothek erheblich. Dieser Plan soll JNI (Java Native Interface) durch ein überlegenes reines Java-Entwicklungsmodell ersetzen, C-Unterstützung bieten und im Laufe der Zeit flexibel genug sein, um die Unterstützung für andere Plattformen wie 32-Bit x86 und zu ermöglichen Fremdfunktionen, die in anderen Sprachen als C geschrieben sind, z. B. C ++. Die Leistung sollte besser als oder vergleichbar mit JNI sein.
  • Verschieben der ZGC-Thread-Stack-Verarbeitung (Z Garbage Collector) von Sicherheitspunkten in eine gleichzeitige Phase. Zu den Zielen dieses Plans gehört das Entfernen der Thread-Stack-Verarbeitung von den ZGC-Sicherheitspunkten. die Stapelverarbeitung faul, kooperativ, gleichzeitig und inkrementell machen; Entfernen aller anderen Thread-Verarbeitung pro Thread von den ZGC-Sicherheitspunkten; und Bereitstellen eines Mechanismus für andere HotSpot VM-Subsysteme zum trägen Verarbeiten von Stapeln. Mit ZGC sollen GC-Pausen und Skalierbarkeitsprobleme in HotSpot der Vergangenheit angehören. Bisher wurden GC-Vorgänge, die mit der Größe des Heaps und der Größe des Metaspaces skaliert werden, aus Safepoint-Vorgängen in gleichzeitige Phasen verschoben. Dazu gehörten Markieren, Verschieben, Referenzverarbeitung, Entladen von Klassen und die meisten Root-Verarbeitungen.Die einzigen Aktivitäten, die noch in GC-Sicherheitspunkten ausgeführt werden, sind eine Teilmenge der Root-Verarbeitung und eine zeitlich begrenzte Markierungsbeendigungsoperation. Diese Roots enthalten Java-Thread-Stacks und andere Thread-Roots, wobei diese Roots problematisch sind, da sie mit der Anzahl der Threads skaliert werden. Um über die aktuelle Situation hinauszugehen, muss die Verarbeitung pro Thread, einschließlich des Stapelscannens, in eine gleichzeitige Phase verschoben werden. Mit diesem Plan sollten die Durchsatzkosten der verbesserten Latenz unbedeutend sein und die Zeit, die in ZGC-Sicherheitspunkten auf typischen Maschinen verbracht wird, sollte weniger als eine Millisekunde betragen.muss in eine gleichzeitige Phase verschoben werden. Mit diesem Plan sollten die Durchsatzkosten der verbesserten Latenz unbedeutend sein und die Zeit, die in ZGC-Sicherheitspunkten auf typischen Maschinen verbracht wird, sollte weniger als eine Millisekunde betragen.muss in eine gleichzeitige Phase verschoben werden. Mit diesem Plan sollten die Durchsatzkosten der verbesserten Latenz unbedeutend sein und die Zeit, die in ZGC-Sicherheitspunkten auf typischen Maschinen verbracht wird, sollte weniger als eine Millisekunde betragen.
  • Eine elastische Metaspace-Funktion, die nicht verwendeten Metadatenspeicher (Metaspace) der HotSpot VM-Klasse schneller an das Betriebssystem zurückgibt, reduziert den Metaspace-Platzbedarf und vereinfacht den Metaspace-Code, um die Wartungskosten zu senken. Metaspace hatte Probleme mit der hohen Auslastung des Off-Heap-Speichers. Der Plan sieht vor, den vorhandenen Speicherzuweiser durch ein Buddy-basiertes Zuordnungsschema zu ersetzen und einen Algorithmus zum Aufteilen des Speichers in Partitionen bereitzustellen, um Speicheranforderungen zu erfüllen. Dieser Ansatz wurde beispielsweise im Linux-Kernel verwendet und macht es praktisch, Speicher in kleineren Blöcken zuzuweisen, um den Overhead des Klassenladeprogramms zu verringern. Die Fragmentierung wird ebenfalls verringert. Darüber hinaus erfolgt die Speicherung des Speichers vom Betriebssystem für Speicherverwaltungsbereiche auf Anfrage träge.um den Platzbedarf für Lader zu verringern, die mit großen Arenen beginnen, diese aber nicht sofort oder möglicherweise nicht in vollem Umfang nutzen. Um die durch die Buddy-Zuweisung gebotene Elastizität voll auszuschöpfen, wird der Metaspace-Speicher in Granulaten mit einheitlicher Größe angeordnet, die unabhängig voneinander festgeschrieben und nicht festgeschrieben werden können.
  • Aktivierung von C ++ 14-Sprachfunktionen, um die Verwendung von C ++ 14-Funktionen im JDK C ++ - Quellcode zu ermöglichen und spezifische Anleitungen zu geben, welche dieser Funktionen im HotSpot VM-Code verwendet werden können. Durch JDK 15 wurden die vom C ++ - Code im JDK verwendeten Sprachfunktionen auf die Sprachstandards C ++ 98/03 beschränkt. Mit JDK 11 wurde der Quellcode aktualisiert, um das Erstellen mit neueren Versionen des C ++ - Standards zu unterstützen. Dies beinhaltet die Möglichkeit, mit neueren Versionen von Compilern zu erstellen, die C ++ 11/14-Sprachfunktionen unterstützen. In diesem Vorschlag werden keine Stil- oder Verwendungsänderungen für C ++ - Code vorgeschlagen, der außerhalb von HotSpot verwendet wird. Um die Funktionen der C ++ - Sprache nutzen zu können, sind je nach Plattform-Compiler einige Änderungen zur Erstellungszeit erforderlich.
  • Eine Vektor-API in einem Inkubatorstadium, in der das JDK mit einem Inkubatormodul ausgestattet würde, jdk.incubator.vector, um Vektorberechnungen auszudrücken, die zu optimalen Vektorhardwareanweisungen auf unterstützten CPU-Architekturen kompiliert werden, um eine überlegene Leistung gegenüber äquivalenten skalaren Berechnungen zu erzielen. Die Vektor-API bietet einen Mechanismus zum Schreiben komplexer Vektoralgorithmen in Java, wobei die bereits vorhandene Unterstützung in der HotSpot-VM für die Vektorisierung verwendet wird, jedoch mit einem Benutzermodell, das die Vektorisierung vorhersehbarer und robuster macht. Zu den Zielen des Vorschlags gehört die Bereitstellung einer klaren und präzisen API zum Ausdrücken einer Reihe von Vektorberechnungen, die plattformunabhängige Unterstützung mehrerer CPU-Architekturen sowie die Bereitstellung einer zuverlässigen Laufzeitkompilierung und -leistung für x64- und AArch64-Architekturen. Anmutige Erniedrigung ist auch ein Ziel,In diesem Fall würde sich eine Vektorberechnung ordnungsgemäß verschlechtern und dennoch funktionieren, wenn sie zur Laufzeit nicht vollständig als Folge von Hardwarevektoranweisungen ausgedrückt werden kann, entweder weil eine Architektur einige Anweisungen nicht unterstützt oder eine andere CPU-Architektur nicht unterstützt wird.
  • Portierung des JDK auf die Windows / AArch64-Plattform. Mit der Veröffentlichung der neuen AArch64 (ARM64) -Hardware der Serverklasse und des Verbrauchers ist Windows / AArch64 aufgrund der Nachfrage zu einer wichtigen Plattform geworden. Während die Portierung selbst bereits größtenteils abgeschlossen ist, liegt der Schwerpunkt dieses Vorschlags auf der Integration des Ports in das Haupt-JDK-Repository.
  • Portierung des JDK auf Alpine Linux und andere Linux-Distributionen, die musl als primäre C-Bibliothek verwenden, auf x64- und AArch64-Architekturen. Musl ist eine Linux-Implementierung der in den ISO C- und Posix-Standards beschriebenen Standardbibliotheksfunktionen. Alpine Linux ist aufgrund seiner geringen Bildgröße in Cloud-Bereitstellungen, Microservices und Containerumgebungen weit verbreitet. Ein Docker-Image für Linux ist kleiner als 6 MB. Wenn Java in solchen Einstellungen sofort einsatzbereit ist, können Tomcat, Jetty, Spring und andere gängige Frameworks in diesen Umgebungen nativ arbeiten. Durch die Verwendung von jlink zur Reduzierung der Java-Laufzeit kann ein Benutzer ein noch kleineres Image erstellen, das auf die Ausführung einer bestimmten Anwendung zugeschnitten ist.
  • Bereitstellung von Datensatzklassen, die als transparente Träger für unveränderliche Daten fungieren. Datensätze können als nominelle Tupel betrachtet werden. Aufzeichnungen wurden in JDK 14 und JDK 15 in der Vorschau angezeigt. Diese Bemühungen sind eine Reaktion auf Beschwerden, dass Java zu ausführlich oder zu zeremoniell war. Zu den Zielen des Plans gehört die Entwicklung eines objektorientierten Konstrukts, das eine einfache Aggregation von Werten ausdrückt, Entwicklern hilft, sich auf die Modellierung unveränderlicher Daten anstatt auf erweiterbares Verhalten zu konzentrieren, automatisch datengesteuerte Methoden wie equalsund Accessoren zu implementieren und langjährige Java-Prinzipien wie nominal beizubehalten Tippen.
  • Das Hinzufügen von Unix-Domain-Socket-Kanälen, bei denen Unix-Domain-Socket-Unterstützung (AF_UNIX) zu den Socket-Kanal- und Server-Socket-Kanal-APIs im Paket nio.channels hinzugefügt wird. Der Plan erweitert auch den Mechanismus für geerbte Kanäle, um Unix-Domain-Socket-Kanäle und Server-Socket-Kanäle zu unterstützen. Unix-Domain-Sockets werden für die Kommunikation zwischen Prozessen auf demselben Host verwendet. Sie ähneln in den meisten Punkten TCP / IP-Sockets, außer dass sie durch Dateisystempfadnamen und nicht durch IP-Adressen und Portnummern adressiert werden. Ziel der neuen Funktion ist es, alle Funktionen von Unix-Domain-Socket-Kanälen zu unterstützen, die für alle wichtigen Unix-Plattformen und Windows gelten. Unix-Domain-Socket-Kanäle verhalten sich in Bezug auf Lese- / Schreibverhalten, Verbindungsaufbau, Akzeptanz eingehender Verbindungen durch Server wie vorhandene TCP / IP-Kanäle.und Multiplexen mit anderen nicht blockierenden auswählbaren Kanälen in einem Selektor. Unix-Domain-Sockets sind sicherer und effizienter als TCP / IP-Loopback-Verbindungen für die lokale Kommunikation zwischen Prozessen.
  • Eine Fremdspeicher-Zugriffs-API, mit der Java-Programme sicher auf Fremdspeicher außerhalb des Java-Heaps zugreifen können. Zuvor sowohl in JDK 14 als auch in JDK 15 inkubiert, wurde die Fremdspeicher-Zugriffs-API in JDK 16 erneut inkubiert, wodurch Verfeinerungen hinzugefügt wurden. Es wurden Änderungen vorgenommen, einschließlich einer klareren Trennung der Rollen zwischen den Schnittstellen MemorySegmentund MemoryAddresses. Zu den Zielen dieses Vorschlags gehört die Bereitstellung einer einzigen API für den Betrieb mit verschiedenen Arten von Fremdspeicher, einschließlich nativem, beständigem und verwaltetem Heapspeicher. Die API sollte die Sicherheit der JVM nicht untergraben. Motivierend für den Vorschlag ist, dass viele Java-Programme auf fremden Speicher zugreifen, z. B. Ignite, Memcached und MapDB. Die Java-API bietet jedoch keine zufriedenstellende Lösung für den Zugriff auf fremden Speicher.
  • Mustervergleich für den instanceofOperator, der auch in JDK 14 und JDK 15 in der Vorschau angezeigt wurde. Er würde in JDK 16 abgeschlossen. Mit dem Mustervergleich kann die allgemeine Logik in einem Programm, nämlich das bedingte Extrahieren von Komponenten aus Objekten, präziser und präziser ausgedrückt werden sicher.
  • Bereitstellung des jpackage-Tools zum Packen von eigenständigen Java-Anwendungen. Jpackage wurde in JDK 14 als Inkubationswerkzeug eingeführt und blieb in JDK 15 in Inkubation. Mit JDK 16 geht jpackage in die Produktion über und unterstützt native Paketformate, um Benutzern ein natürliches Installationserlebnis zu bieten und die Angabe von Startzeitparametern zum Zeitpunkt der Verpackung zu ermöglichen. Zu den Formaten gehören msi und exe unter Windows, pkg und dmg unter MacOS sowie deb und rpm unter Linux. Das Tool kann direkt über die Befehlszeile oder programmgesteuert aufgerufen werden. Das neue Verpackungstool behebt eine Situation, in der viele Java-Anwendungen auf nativen Plattformen auf erstklassige Weise installiert werden müssen, anstatt auf dem Klassen- oder Modulpfad platziert zu werden. Ein installierbares Paket, das für die native Plattform geeignet ist, wird benötigt.
  • Migration von OpenJDK-Quellcode-Repositorys von Mercurial nach Git. Diese Bemühungen werden durch die Metadatengröße des Versionskontrollsystems sowie die verfügbaren Tools und das Hosting vorangetrieben.
  • Migration zu GitHub im Zusammenhang mit der Mercurial-zu-Git-Migration mit JDK 16-Quellcode-Repositorys auf der beliebten Code-Sharing-Site. JDK-Feature-Releases und JDK-Update-Releases für Java 11 und höher wären Teil dieses Plans. Der Übergang zu Git, GitHub und Skara für das Mercurial JDK und die JDK-Sandbox erfolgte am 5. September und ist offen für Beiträge.  

Early-Access-Builds von JDK 16 für Linux, Windows und MacOS finden Sie unter jdk.java.net. Wie JDK 15 wird JDK 16 eine kurzfristige Version sein, die sechs Monate lang unterstützt wird. JDK 17, das im September 2021 fällig wird, wird eine LTS-Version (Long Term Support) sein, die mehrere Jahre lang unterstützt wird. Die aktuelle LTS-Version JDK 11 wurde im September 2018 veröffentlicht.