
Sechs Monate sind vergangen, was bedeutet, dass es Zeit ist, neues Java zu installieren ! Es war eine lange Reise, und nur wenige erreichten das Ende. Rohe Linien fielen von interessanten JEPs, aber wir werden über den Rest unter dem Schnitt sprechen.
Wie läuft alles?
Die Veröffentlichung der neuen Java-Version erfolgt nach dem neuen „beschleunigten“ Veröffentlichungszyklus mit einer Länge von etwa sechs Monaten. Die genauen Daten sind auf der Projektseite festgelegt . Es gab mehrere Hauptphasen für JDK 12:
- 2018/12/13 - Die erste Phase der Verlangsamung (in diesem Moment wird eine Gabelung aus dem Hauptzweig im Repository hergestellt);
- 17.01.2019 - Die zweite Phase der Verlangsamung (alles Mögliche abschließen);
- 2019/02/07 - Release Candidate (nur die wichtigsten Fehler wurden behoben);
- 19.03.2019 - Veröffentlichung, Allgemeine Verfügbarkeit. <- du bist hier
Was haben wir aus diesem Zeitplan? Ja, in der Tat nichts - wir sind gerade am Ziel angekommen und beobachten die Liebhaber des Vermächtnisses aus einer Höhe des brandneuen, frischen JDK 12.
Bugs! Panik! Alles auf den Grund!

Wenn eine neue Nicht-LTS-Version herauskommt, kümmern sich normalerweise nicht alle um neue Funktionen. Es ist interessanter, wenn alles zur Hölle zerfällt.
Natürlich gibt es viele Fehler, aber nicht in JDK 12 :) Nach dem Jir zu urteilen, ist alles normal:

Ich werde die Anfrage zitieren, damit Sie genau verstehen , was die "Norm" ist:
project = JDK AND issuetype = Bug AND status in (Open, "In Progress", New) AND priority in (P1) AND (fixVersion in (12) OR fixVersion is EMPTY AND affectedVersion in (12) AND affectedVersion not in regexVersion("11.*", "10.*", "9.*", "8.*", "7.*", "6.*")) AND (labels is EMPTY OR labels not in (jdk12-defer-request, noreg-demo, noreg-doc, noreg-self)) AND (component not in (docs, globalization, infrastructure) OR component = infrastructure AND subcomponent = build) AND reporter != "Shadow Bug" ORDER BY priority, component, subcomponent, assignee
Natürlich haben Bugs im Allgemeinen einen Platz, an dem sie in einem so großen Projekt nirgendwo hingehen können. Es wird nur behauptet, dass P1-Fehler derzeit nicht bemerkt wurden.
Eine formellere Kommunikation mit Fehlern wird in einem speziellen Dokument, JEP 3: JDK Release Process, erklärt , das unserem unsterblichen Steward auf den turbulenten Wellen des Java-Ozeans gehört - Mark Reinhold.
Insbesondere lohnt es sich, einen Absatz zu lesen Wer ist schuld und was zu tun So übertragen Sie Tickets, wenn Sie keine Zeit für die 12. Veröffentlichung haben. Es ist notwendig, im Bugtracker das Label jdk$N-defer-request
in dem N angibt, von welcher Version Sie übertragen möchten, und einen Kommentar zu hinterlassen, dessen erste Zeile Deferral Request ist . Darüber hinaus wird die Überprüfung aller derartigen Anfragen von den Leitern der jeweiligen Bereiche und Projekte vorgenommen.
Die Probleme beim Übergeben von TCK können auf diese Weise nicht ignoriert werden - es wird garantiert, dass Java Java bleibt und nicht etwas Froschartiges. Das jdk$N-defer-request label
verschwindet nie. Es ist interessant, was sie mit Menschen machen, die gegen die Regel verstoßen, Tags nicht zu löschen - ich schlage vor, Meerschweinchen zu füttern.
Auf diese Weise können Sie jedoch sehen, wie viele Fehler auf JDK 13 portiert wurden. Versuchen wir diese Abfrage:
project = JDK AND issuetype = Bug AND status in (Open, "In Progress", New) AND (labels in (jdk12-defer-request) AND labels not in (noreg-demo, noreg-doc, noreg-self)) AND (component not in (docs, globalization, infrastructure) OR component = infrastructure AND subcomponent = build) AND reporter != "Shadow Bug" ORDER BY priority, component, subcomponent, assignee
Nur 1 Stück, JDK-8216039 : "TLS mit BC und RSASSA-PSS bricht ECDHServerKeyExchange". Es ist nicht dick. Wenn dieses Argument immer noch nicht hilft, empfehle ich als Ihr Anwalt, ein Beruhigungsmittel zu probieren.
Und was ist das Endergebnis?

Es ist klar, dass die meisten Funktionen keine Benutzer (Java-Programmierer) betreffen, sondern Entwickler von OpenJDK. Daher teile ich Features für alle Fälle in externe und interne ein . Sie können die internen überspringen, aber ich bin beleidigt, ich habe so viel Text geschrieben.
189: Shenandoah: Ein Müllsammler mit geringer Pause (experimentell)
Externe Funktion . Kurz gesagt, die Leute mögen es nicht, wenn Java langsamer wird, insbesondere wenn die SLA eine Reaktionsfähigkeit in der Größenordnung von 10 bis 500 Millisekunden erfordert. Wir haben jetzt einen kostenlosen Low-Punch-GC, der versucht, näher am linken Rand dieses Bereichs zu arbeiten. Der Nachteil ist, dass wir die CPU und den RAM austauschen, um die Latenz zu reduzieren. Hip-Tagging- und Verdichtungsphasen arbeiten parallel zu Live-Anwendungsthreads. Die verbleibenden kleinen Pausen sind darauf zurückzuführen, dass Sie noch die Wurzeln des Objektdiagramms suchen und aktualisieren müssen.
Wenn keiner der oben genannten Punkte für Sie einen Sinn ergibt - es spielt keine Rolle, funktioniert Shenandoah einfach , unabhängig davon, ob Sie die zugrunde liegenden Prozesse verstehen oder nicht verstehen.
Alexei Shipilev, Christina Flood und Roman Kennke arbeiten daran - Sie müssen sich bemühen, nichts über diese Leute zu wissen. Wenn Sie allgemein verstehen, wie GC funktioniert, aber nicht wissen, was ein Entwickler dort tun kann, empfehlen wir Ihnen, sich die wunderbare Übersetzung des wundervollen Leshina-Artikels "Homemade Garbage Collector für OpenJDK" oder der JVM Anatomy Quarks- Reihe anzusehen. Das ist sehr interessant .
Sehr wichtig. Oracle hat beschlossen, Sheandoah nicht mit einem seiner Release-Builds zu versenden - weder mit dem auf jdk.java.net noch mit dem auf oracle.com. Angesichts der Tatsache, dass Shenandoah eines der wichtigsten Merkmale von JDK 12 ist, lohnt es sich, eine andere offizielle Versammlung zu installieren, beispielsweise von Azul .
230: Microbenchmark Suite
Inneres Merkmal . Wenn Sie jemals versucht haben, Mikrobenchmarks zu schreiben, wissen Sie, dass dies auf JMH erfolgt. JMH ist ein Framework zum Erstellen, Zusammenstellen, Starten und Analysieren von Mikrobenchmarks für Java und andere JVM-Sprachen. Sie wissen selbst, wer es geschrieben hat (alle Übereinstimmungen sind zufällig). Leider kann nicht alles, was in der Welt der "normalen" Anwendungen getan wird, innerhalb des JDK angewendet werden. Beispielsweise ist es unwahrscheinlich, dass dort jemals normaler Spring Framework-Code angezeigt wird.
Glücklicherweise können Sie ab Version 12 mindestens JMH verwenden, und es gibt bereits eine Reihe von Tests, die darauf geschrieben sind. Sie können es in jdk/jdk/test/micro/org/openjdk/bench
(Sie können direkt im Browser nachsehen, dieser Pfad ist ein Link).
So sieht beispielsweise der GC-Test aus.
Ich möchte Sie daran erinnern, dass wir hier keinen StackOverflow haben und es verboten ist, den Code aus Copy-Paste hier und im Folgenden zu verwenden, ohne alle Lizenzen aus der entsprechenden Datei und dem OpenJDK-Projekt im Allgemeinen zu lesen und zu beobachten, da Sie sonst leicht die letzten zu verklagenden Socken bekommen.
@BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) public class Alloc { public static final int LENGTH = 400; public static final int ARR_LEN = 100; public int largeLen = 100; public int smalllen = 6; @Benchmark public void testLargeConstArray(Blackhole bh) throws Exception { int localArrlen = ARR_LEN; for (int i = 0; i < LENGTH; i++) { Object[] tmp = new Object[localArrlen]; bh.consume(tmp); } }
325: Ausdrücke wechseln (Vorschau)
Externe Funktion . Dies wird Ihre Herangehensweise an das Schreiben von Endlosschaltern mit einer Länge von mehr als zwei Bildschirmen grundlegend ändern. Schauen Sie:
Virgin Java Switch vs ...
int dayNum = -1; switch (day) { case MONDAY: case FRIDAY: case SUNDAY: dayNum = 6; break; case TUESDAY: dayNum = 7; break; case THURSDAY: case SATURDAY: dayNum = 8; break; case WEDNESDAY: dayNum = 9; break; }
Warum es so schlimm ist : Es gibt viele Buchstaben, Sie können die Pause überspringen (insbesondere, wenn Sie drogenabhängig sind oder an ADHS leiden).
... gegen Chad Java Swtich Expression!
int dayNum = switch (day) { case MONDAY -> 0; case TUESDAY -> 1; default -> { int k = day.toString().length(); int result = f(k); break result; } };
Warum gut : wenige Buchstaben, sicher, praktisch, neue coole Funktion.
Bonus : Wenn Sie ein Sadist sind, werden Sie zutiefst zufrieden sein, da Tausende von IDE-Entwicklern jetzt mit der Unterstützung dieser Funktion gequält werden. Ja Lany , ja? Sie können ihn nach dem Bericht am 6. April fangen und sanft darum bitten, alle schmutzigen Details preiszugeben.
Dies ist eine Vorschaufunktion, die einfach nicht funktioniert! Beim Kompilieren müssen Sie in --enable-preview --release 12
die Befehlszeilenoptionen --enable-preview --release 12
und java
ausführen - nur das --enable-preview
.
334: JVM-Konstanten-API
Inneres Merkmal . Entwickler möchten Klassendateien bearbeiten. Sie müssen dies bequem tun, und dies ist die Erklärung des Problems. Zumindest sagte Brian Goetz, dem dieser JEP gehört :-) All dies ist Teil eines größeren Schlachtfeldes, aber im Moment werden wir nicht tief gehen.
Jede Java-Klasse verfügt über einen sogenannten "Konstantenpool", in dem entweder einige Werte (wie Zeichenfolgen und Ints) oder Laufzeitentitäten wie Klassen und Methoden gespeichert werden. Sie können in diesen Speicherauszug mit der Anweisung ldc - "load costant" graben, sodass all dieser Müll als ladbare Konstanten bezeichnet wird. Es gibt immer noch einen Sonderfall für invokedynamic, aber egal.
Wenn wir mit Klassendateien arbeiten, möchten wir bequem Bytecode-Instrumente und damit ladbare Konstanten simulieren. Der erste Wunsch besteht darin, einfach die entsprechenden Java-Typen zu erstellen. Wie präsentieren Sie ihnen jedoch eine "lebende" Klasse, die CONSTANT_Class_info
Struktur? Klassenobjekte hängen von der Richtigkeit und Konsistenz des Ladens von Klassen ab, und beim Laden von Klassen in Java wird eine höllische Bacchanalia erstellt. Zunächst können nicht alle Klassen in die VM geladen werden, aber Sie müssen sie noch beschreiben!
Ich möchte Dinge wie Klassen, Methoden und weniger bekannte Bestien wie Methodenhandles und dynamische Konstanten unter Berücksichtigung all dieser Feinheiten irgendwie verwalten.
Dies wird gelöst, indem neue wertbasierte Typen symbolischer Verknüpfungen (im Sinne von JVMS 5.1 ) eingeführt werden, von denen jede einen bestimmten Konstantentyp beschreibt. Beschreibt rein nominell, isoliert von Ladeklassen oder Zugriffsproblemen. Sie leben in Paketen wie java.lang.invoke.constant
und fragen nicht danach, aber Sie können sich den Patch hier ansehen .
340: Ein AArch64-Port, nicht zwei
Externe Funktion . Bereits in JDK 9 gab es eine seltsame Situation, als Oracle und Red Hat gleichzeitig ihre ARM-Ports in Alarmbereitschaft versetzten. Und jetzt sehen wir das Ende der Geschichte: Der 64-Bit-Teil des Oraklov-Ports wurde vom Upstream entfernt.
Sie hätten selbst lange in die Geschichte eintauchen können, aber es gibt einen besseren Weg. BellSoft war an der Entwicklung dieses JEP beteiligt. Das Büro befindet sich in St. Petersburg neben dem ehemaligen Büro von Oracle.
Deshalb habe ich mich sofort an Alexey Voitilov, CTO von BellSoft, gewandt:
"BellSoft bringt das Liberica JDK auf den Markt, das neben x86 Linux / Windows / Mac und Solaris / SPARC auch ARM unterstützt. Ab JDK 9 für ARM konzentrierten wir uns auf die Verbesserung der Leistung des AARCH64-Ports für Serveranwendungen und unterstützten weiterhin den 32-Bit-ARM-Port für Zum Zeitpunkt der Veröffentlichung von JDK 11 gab es also eine Situation, in der niemand den 64-Bit-Port-Teil von Oracle (einschließlich Oracle) unterstützte, und die OpenJDK-Community beschloss, ihn zu entfernen, um sich auf den AARCH64-Port zu konzentrieren. Im Moment ist er produktiver ( siehe zum Beispiel JEP 315 , die wir integriert in JDK 11) und unterstützt ab JDK 12 alle Funktionen des Ports von Oracle (die letzte, Minimal VM, die ich im September integriert habe). Daher war ich froh, Bob Vandette dabei zu helfen, dieses Rudiment in JDK 12 zu entfernen. Infolgedessen OpenJDK Die Community erhielt einen Port auf AARCH64 und einen ARM32-Port, was die Unterstützung sicherlich erleichtert. "
341: Standard-CDS-Archive
Inneres Merkmal . Das Problem ist, dass beim Start einer Java-Anwendung Tausende von Klassen geladen werden, was das Gefühl erzeugt, dass Java beim Start erheblich langsamer wird. Aber wer da ist, um zu lügen, das ist nicht nur eine „Sensation“ - es ist so. Um das Problem aus alten Zeiten zu beheben, werden verschiedene Rituale praktiziert.
Die gemeinsame Nutzung von Klassendaten ist eine Funktion, die uns seit Jahrhunderten zur Verfügung steht , wie eine kommerzielle Funktion aus JDK 8 Update 40. Sie ermöglicht es Ihnen, all diesen Startmüll in ein Archiv eines eigenen Formats zu packen (Sie müssen nicht wissen, welches) und danach die Startgeschwindigkeit Anwendungen nimmt zu. Und nach einer Weile erschien JEP 310 : Application Class-Data Sharing, mit dem wir nicht nur mit Systemklassen, sondern auch mit Anwendungsklassen auf die gleiche Weise arbeiten konnten.
Für JDK-Klassen sieht es so aus. Zuerst java -Xshare:dump
wir die Klassen mit dem Befehl java -Xshare:dump
und führen dann die Anwendung aus, um diesen Cache zu verwenden: java -Xshare:on -jar app.jar
. Alles, das Startup hat sich etwas verbessert. Wussten Sie schon über diese Funktion? Viele, die es noch nicht wissen!
Hier sieht es seltsam aus: Warum jedes Mal rituell -Xshare:dump
schreiben -Xshare:dump
wenn das Standardergebnis dieses Befehls selbst in der Phase der Erstellung der JDK-Distribution leicht vorhersehbar ist? Wenn die Java 8-Distribution laut Dokumentation mit dem Installationsprogramm installiert wurde, sollte sie zum Zeitpunkt der Installation die erforderlichen Befehle für Sie ausführen. Als ob der Installer leise in der Ecke abbaut. Aber warum? Und was tun mit der Distribution, die nicht als Installationsprogramm, sondern als Zip-Datei verteilt wird?
Es ist ganz einfach: Ab JDK 12 wird das CDS-Archiv unmittelbar nach dem Verknüpfen von den Erstellern des Distributionskits generiert. Auch für Nacht-Builds (vorausgesetzt, sie sind 64-Bit und nativ, nicht für die Cross-Kompilierung).
Benutzer müssen nicht einmal über das Vorhandensein dieser Funktion Bescheid wissen, da ab JDK 11 -Xshare:auto
standardmäßig aktiviert ist und ein solches Archiv automatisch -Xshare:auto
wird. Die bloße Aktualisierung auf JDK 12 beschleunigt somit den Start der Anwendung!
344: Abbruchfähige gemischte Sammlungen für G1
Inneres Merkmal . Um ehrlich zu sein, Ich verstehe nichts in der Arbeit von G1 Eine Erklärung der Funktionen von GC ist eine undankbare Aufgabe. Es erfordert ein Verständnis der Details seiner Arbeit sowohl vom Erklärenden als auch vom Verstehen. Für die meisten Menschen ist GC eine Art Hölle aus einer Schnupftabakdose, die man im Falle von etwas betrügen kann. Daher muss das Problem irgendwie einfacher erklärt werden.
Problem : G1 könnte besser funktionieren.
Nun, das Problem ist, dass der GC ein Kompromiss vieler Parameter ist, von denen einer die Länge der Pause ist. Manchmal ist die Pause zu lang und dann ist es schön, sie abbrechen zu können.
Wann passiert das? G1 analysiert das Verhalten der Anwendung wirklich und wählt den Arbeitsbereich (ausgedrückt als Sammlungssatz ) anhand seiner Schlussfolgerungen aus. Wenn der Arbeitsumfang genehmigt ist, verpflichtet sich G1, alle lebenden Gegenstände im Sammelset hartnäckig und ohne Unterbrechung in einer Sitzung zu sammeln. Manchmal dauert es zu lange. Im Wesentlichen bedeutet dies, dass G1 den Arbeitsaufwand falsch berechnet hat. Sie können ihn täuschen, indem Sie plötzlich das Verhalten Ihrer Anwendung ändern, sodass die Heuristik zusätzlich zu schlechten Daten funktioniert, wenn zu viele alte Regionen in den Sammlungssatz aufgenommen werden.
Um aus der Situation herauszukommen, wurde G1 durch den folgenden Mechanismus finalisiert: Wenn die Heuristik regelmäßig den falschen Arbeitsaufwand auswählt, wechselt G1 Schritt für Schritt zur inkrementellen Speicherbereinigung, und jeder nächste Schritt (wenn er nicht in die Zielausführungszeit passt) kann abgebrochen werden. Es ist nicht sinnvoll, etwas inkrementell zu sammeln (junge Regionen), daher werden alle diese Arbeiten im „obligatorischen“ Block hervorgehoben, der immer noch kontinuierlich durchgeführt wird.
Was tun mit dem Endbenutzer? Nichts, Sie müssen auf JDK 12 aktualisieren, alles wird von selbst besser.
346: Nicht verwendeten festgeschriebenen Speicher sofort von G1 zurückgeben
Inneres Merkmal . Das Problem ist, dass wenn wir eine große Hüfte haben, die niemand aktiv nutzt, es fair erscheint, all diesen inaktiven Speicher wieder auf das Betriebssystem zu übertragen. Vor JDK 12 war dies jedoch nicht der Fall.
Um sein Ziel hinsichtlich der zulässigen Pausenlänge zu erreichen, führt G1 eine Reihe von inkrementellen, parallelen und mehrstufigen Zyklen durch. In JDK 11 wird dem Betriebssystem nur mit vollem GC oder während der parallelen Markierungsphase festgeschriebener Speicher zugewiesen. Wenn Sie die Protokollierung verbinden (-Xloggc: /home/gc.log -XX: + PrintGCDetails -XX: + PrintGCDateStamps), wird diese Phase wie folgt angezeigt:
8801.974: [G1Ergonomics (Concurrent Cycles) request concurrent cycle initiation, reason: occupancy higher than threshold, occupancy: 12582912000 bytes, allocation request: 0 bytes, threshold: 12562779330 bytes (45.00 %), source: end of GC] 8804.670: [G1Ergonomics (Concurrent Cycles) initiate concurrent cycle, reason: concurrent cycle initiation requested] 8805.612: [GC concurrent-mark-start] 8820.483: [GC concurrent-mark-end, 14.8711620 secs]
Das Lustige ist, dass G1, wie es kann, mit vollständigen Stopps zu kämpfen hat und der gleichzeitige Zyklus nur mit häufigen Zuweisungen und einem verstopften Haufen beginnt. Unsere Situation, in der niemand die Hüfte berührt, ist genau das Gegenteil. Situationen, in denen G1 kratzt, um dem Betriebssystem Speicher zu geben, treten sehr selten auf!
Jeder hätte bei diesem Problem ein Tor erzielt („kaufe noch mehr RAM, was wie ein Schurke ist!“). Wenn nicht einer, aber - es gibt alle Arten von Wolken und Containern, in denen dies eine unzureichende Nutzung und den Verlust von ernsthaftem Geld bedeutet. Schau, was für ein cooler Bericht , randvoll mit Schmerz.
Die Lösung bestand darin, G1 beizubringen, sich in diesem speziellen Fall gut zu verhalten, wie Shenanda oder GenCon von OpenJ9 bereits wissen. Es ist notwendig, die unzureichende Auslastung der Hüfte festzustellen und ihre Verwendung entsprechend zu reduzieren. Bei einigen Tests mit Tomcat konnte der Speicherverbrauch dadurch um fast die Hälfte reduziert werden.
Unter dem Strich wird die Anwendung als inaktiv betrachtet oder wenn das Intervall (in Millisekunden) seit dem letzten Build getloadavg()
ist und kein gleichzeitiger Zyklus getloadavg()
oder wenn getloadavg()
für einen Zeitraum von einer Minute eine Last unter einem bestimmten Schwellenwert getloadavg()
. Sobald dies passiert ist, beginnt die regelmäßige Speicherbereinigung - sie wird zwar nicht so sauber wie die gesamte Baugruppe, wirkt sich jedoch nur minimal auf die Anwendung aus.
Sie können es in dieses Protokoll verschieben:
(1) [6.084s][debug][gc,periodic ] Checking for periodic GC. [6.086s][info ][gc ] GC(13) Pause Young (Concurrent Start) (G1 Periodic Collection) 37M->36M(78M) 1.786ms (2) [9.087s][debug][gc,periodic ] Checking for periodic GC. [9.088s][info ][gc ] GC(15) Pause Young (Prepare Mixed) (G1 Periodic Collection) 9M->9M(32M) 0.722ms (3) [12.089s][debug][gc,periodic ] Checking for periodic GC. [12.091s][info ][gc ] GC(16) Pause Young (Mixed) (G1 Periodic Collection) 9M->5M(32M) 1.776ms (4) [15.092s][debug][gc,periodic ] Checking for periodic GC. [15.097s][info ][gc ] GC(17) Pause Young (Mixed) (G1 Periodic Collection) 5M->1M(32M) 4.142ms (5) [18.098s][debug][gc,periodic ] Checking for periodic GC. [18.100s][info ][gc ] GC(18) Pause Young (Concurrent Start) (G1 Periodic Collection) 1M->1M(32M) 1.685ms (6) [21.101s][debug][gc,periodic ] Checking for periodic GC. [21.102s][info ][gc ] GC(20) Pause Young (Concurrent Start) (G1 Periodic Collection) 1M->1M(32M) 0.868ms (7) [24.104s][debug][gc,periodic ] Checking for periodic GC. [24.104s][info ][gc ] GC(22) Pause Young (Concurrent Start) (G1 Periodic Collection) 1M->1M(32M) 0.778ms
Herausgefunden? Ich nicht. In JEP gibt es eine detaillierte Übersetzung der Gebärdensprache für jede Zeile des Protokolls, die Funktionsweise des Algorithmus und alles andere.
"Also was, warum habe ich es herausgefunden?" - Du fragst. Jetzt haben wir zwei zusätzliche Handles: G1PeriodicGCInterval
und G1PeriodicGCSystemLoadThreshold
, die verdreht werden können, wenn es schlecht wird. Es ist sicher, dass es eines Tages schlecht wird, es ist Java, Baby!
Zusammenfassung
Infolgedessen haben wir eine starke Befreiung in unseren Händen - keine Revolution, sondern eine Entwicklung, die auf die Verbesserung der Leistung ausgerichtet ist. Genau die Hälfte der Verbesserungen hängt mit der Leistung zusammen: Drei JEPs zu GC und eine zu CDS, die sich selbst aktivieren lassen, müssen nur auf JDK 12 aktualisiert werden. Außerdem haben wir eine Sprachfunktion (Switch-Ausdrücke) und zwei neue Tools für JDK-Entwickler erhalten ( Konstante API- und JMH-Tests), und jetzt kann sich die Community besser auf einen einzelnen 64-Bit-Port in ARM konzentrieren.
Aktualisieren Sie im Allgemeinen jetzt auf JDK 12, und die Force ist möglicherweise bei Ihnen. Du wirst es brauchen.
Minute der Werbung. Sehr bald, vom 5. bis 6. April, wird die JPoint-Konferenz stattfinden, auf der eine große Anzahl von Menschen zusammenkommen wird, die viel über JDK und alle möglichen neuen Funktionen wissen. Zum Beispiel wird es sicherlich Simon Ritter aus Azul geben, der einen Vortrag über „JDK 12: Fallstricke für Unvorsichtige“ hält . Der am besten geeignete Ort, um die neueste Version zu diskutieren! Weitere Informationen zu JPoint finden Sie auf der offiziellen Website .