JavaRush /Java-Blog /Random-DE /Von 8 bis 13: eine vollständige Übersicht über die Java-V...

Von 8 bis 13: eine vollständige Übersicht über die Java-Versionen. Teil 2

Veröffentlicht in der Gruppe Random-DE
Dieser Artikel ist der zweite Teil meiner Rezension zu Neuerungen in den Java-Versionen 8-13. Der erste Teil ist hier . Gehen wir ohne Umschweife weiter: zum 25. September 2018, als das neue JDK veröffentlicht wurde:

Java 11

Von 8 bis 13: eine vollständige Übersicht über die Java-Versionen.  Teil 2 - 1

var (in Lambda)

Von nun an können wir die Typen von Lambda-Parametern angeben oder sie weglassen, wenn wir einen Lambda-Ausdruck schreiben (implizit typisierte Lambda-Ausdrücke):
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Sie können auch Anmerkungen zu Lambda-Parametern hinzufügen, ohne den vollständigen Namen des Variablentyps schreiben zu müssen:
Function<String, String> append = (@NonNull var string) -> string + " Text";

Z(ZGC)

ZGC ist ein neuer Garbage Collector, der nicht funktioniert. Es weist neuen Speicher zu, startet ihn jedoch nie neu. ZGC verspricht die Verwaltung großer Speichermengen mit hohem Durchsatz und geringer Latenz (ZGC ist nur auf 64-Bit-Plattformen verfügbar). Referenzfärbung – ZGC verwendet 64-Bit-Zeiger mit einer Technik namens Zeigerfärbung. Farbige Zeiger speichern zusätzliche Informationen zu Objekten auf dem Heap. Wenn der Speicher fragmentiert wird, kann dies dazu beitragen, Leistungseinbußen zu vermeiden, wenn der GC Platz für eine neue Zuweisung finden muss. Die Garbage Collection mit ZGC besteht aus den folgenden Schritten:
  1. Weltstopps: Wir suchen nach Ausgangspunkten, um Objekte auf dem Heap zu erreichen (z. B. lokale Variablen oder statische Felder).
  2. Schnittmenge von Objektgraphen ausgehend von Stammverknüpfungen. Wir markieren jedes Objekt, das wir erreichen (ZGC geht durch den Objektgraphen und untersucht die farbigen Markierungen, um verfügbare Objekte zu markieren);
  3. Umgang mit einigen Randfällen, wie z. B. schwachen Links;
  4. Bewegen Sie lebende Objekte und geben Sie große Bereiche des Haufens frei, um die Zuordnung zu beschleunigen.
  5. Wenn die Verschiebungsphase beginnt, teilt ZGC den Heap in Seiten auf und bearbeitet jeweils eine Seite.
  6. Der ZGC beendet die Bewegung aller Wurzeln und der Rest der Bewegung wird ausgeführt.
Dieses Thema ist sehr komplex und verwirrend. Eine ausführliche Diskussion würde einen separaten Artikel erfordern, daher belasse ich ihn hier:

Epsilon GC

Epsilon ist ein Garbage Collector, der die Speicherzuweisung übernimmt, aber keinen echten Mechanismus zur Speicherwiederherstellung implementiert. Sobald der verfügbare Java-Heap erschöpft ist, wird die JVM heruntergefahren. Das heißt, wenn Sie mit diesem Garbage Collector beginnen, ein Objekt in einem unendlichen Array zu erstellen, ohne an eine Referenz zu binden, stürzt die Anwendung mit einem OutOfMemoryError ab (und bei jedem anderen nicht, da Objekte ohne Referenzen bereinigt werden). . Warum wird es benötigt? Hier ist der Grund:
  1. Leistungstest.
  2. Gedächtnisdrucktest.
  3. Testen der VM-Schnittstelle.
  4. Extrem kurze Arbeit.
  5. Verbesserungen der Last-Drop-Latenz.
  6. Verbesserungen des Last-Drop-Durchsatzes.
Nützliche Links: Weitere Neuerungen:
  1. ByteArrayOutputStreamHabe eine Methode void writeBytes(byte []), die alle Bytes vom Argument nach schreibt OutputStream.
  2. FileReaderund FileWriterhat neue Konstruktoren erhalten, mit denen Sie Charset angeben können.
  3. Pathhat sich zwei neue Methoden geholt, gibt von einem String-Argument einen Pfad oder eine Folge von Strings of(String, String [])zurück Path, die zusammen einen Pfad-String bilden, und of(URI): gibt Path von einem URI zurück.
  4. Pattern– hat eine Methode erhalten asMatchPredicate(), die prüft, ob eine bestimmte Eingabezeichenfolge mit einem bestimmten Muster übereinstimmt (ob sie die Erstellung eines Prädikats mithilfe eines regulären Ausdrucks ermöglicht, sodass Sie beispielsweise Daten im Stream filtern können).
  5. StringIch habe viele nützliche Methoden gelernt, wie zum Beispiel:
    • String strip(): gibt uns einen String zurück, der dieser String ist, wobei alle Leerzeichen am Anfang und Ende des Strings entfernt wurden (ähnlich wie trim(), definiert Leerzeichen jedoch anders);
    • String stripLeading(): gibt uns die Zeichenfolge zurück, die diese Zeichenfolge ist, und entfernt alle führenden Leerzeichen aus der Zeichenfolge;
    • String stripTrailing(): gibt uns die Zeichenfolge zurück, die diese Zeichenfolge ist, und entfernt alle Leerzeichen am Ende der Zeichenfolge.
    • Stream lines(): gibt uns Streamvon zurück String, extrahiert aus dieser Zeichenfolge, getrennt durch Zeilentrennzeichen;
    • String repeat(int): gibt uns eine Zeichenfolge zurück, die eine Verkettung dieser Zeichenfolge ist und mehrmals wiederholt wird.
    • boolean isBlank(): Gibt true zurück, wenn die Zeichenfolge leer ist oder nur Leerzeichen enthält, andernfalls false.
  6. Thread— Methoden destroy() und stop(Throwable) wurden entfernt.
  7. FilesHabe eine Reihe neuer Methoden erhalten:
    • String readString(Path): Liest alle Daten aus einer Datei in eine Zeichenfolge und dekodiert sie dabei mithilfe der UTF-8-Kodierung von Bytes in Zeichen.
    • String readString(Path, Charset): das Gleiche wie in der obigen Methode, mit dem Unterschied, dass die Dekodierung von Bytes in Zeichen unter Verwendung des angegebenen Zeichensatzes erfolgt;
    • Path writeString (Path, CharSequence, OpenOption []): Schreibt eine Zeichenfolge in eine Datei. Zeichen werden mithilfe der UTF-8-Kodierung in Bytes kodiert;
    • Path writeString(Path, CharSequence,Charset, OpenOption []): Dieselbe Methode wie oben, nur Zeichen werden mithilfe der in Charset angegebenen Codierung in Bytes codiert.
Dies waren die interessantesten API-Innovationen (meiner bescheidenen Meinung nach). Hier sind ein paar Materialien für eine detailliertere Überprüfung:

Java 12

Sechs Monate vergehen und wir sehen die nächste Stufe in der Entwicklung von Java. Es ist also an der Zeit, eine Schaufel voller Wissen hervorzuholen und zu graben. Von 8 bis 13: eine vollständige Übersicht über die Java-Versionen.  Teil 2 - 2

G1 aktualisieren

Für G1 wurden folgende Verbesserungen vorgenommen:
  1. Fordern Sie ungenutzten zugewiesenen Speicher zurück

    Im Java-Heapspeicher gibt es so etwas wie ungenutzten Speicher (oder mit anderen Worten inaktiven). In Java 12 haben sie beschlossen, dieses Problem jetzt zu beheben:

    • G1 gibt in einem vollständigen GC oder während einer Parallelschleife Speicher vom Heap zurück; G1 versucht, eine vollständige GC zu verhindern und startet eine parallele Schleife basierend auf der Heap-Zuweisung. Wir müssen G1 zwingen, Speicher vom Heap zurückzugeben.

    Diese Verbesserung konzentriert sich auf die Leistung, indem automatisch Speicher vom Heap an das Betriebssystem zurückgegeben wird, wenn G1 nicht verwendet wird.

  2. Abbruch gemischter Sammlungen, wenn die Pausenzeit überschritten wird

    G1 verwendet eine Analyse-Engine, um den für die Garbage Collection erforderlichen Arbeitsaufwand auszuwählen. Es sammelt lebende Objekte, ohne anzuhalten, nachdem der Satz definiert und die Bereinigung gestartet wurde. Dies führt dazu, dass der Garbage Collector sein Pausenzeitziel überschreitet. Tatsächlich wird dieses Problem durch die Verbesserung gelöst, da dieser Schritt unterbrochen werden kann, wenn die für die Durchführung des nächsten Schritts erforderliche Zeit außerhalb der angemessenen Grenzen liegt.

Mikrobenchmark

Mit Java 12 wurden Mikrobenchmarking-Tests eingeführt, damit die JVM-Leistung einfach mithilfe vorhandener Benchmarks getestet werden kann. Dies wäre sehr nützlich für jeden, der an der JVM selbst arbeiten möchte. Die hinzugefügten Tests werden mit Java Microbenchmark Harness (JMH) erstellt. Diese Tests ermöglichen kontinuierliche Leistungstests auf der JVM. JEP 230 schlägt die Einführung von etwa 100 Tests vor, wobei neue Tests eingeführt werden, wenn neue Java-Versionen veröffentlicht werden. Hier ist ein Beispiel für die hinzugefügten Tests .

Shenandoah

Hierbei handelt es sich um einen Garbage-Collection-Algorithmus (GC), der darauf abzielt, kurze Antwortzeiten zu gewährleisten (untere Grenze liegt bei 10–500 ms). Dies reduziert die GC-Pausenzeit, wenn Bereinigungsarbeiten gleichzeitig mit der Ausführung von Java-Threads durchgeführt werden. In Shenandoah ist die Pausenzeit unabhängig von der Heap-Größe. Dies bedeutet, dass die Pausenzeit unabhängig von der Größe Ihres Heaps gleich ist. Dies ist eine experimentelle Funktion und nicht im Standard-Build (Oracle) von OpenJDK enthalten.

Schalter verbessern

Java 12 hat Switch-Ausdrücke für den Mustervergleich verbessert. Eine neue Syntax L → wurde eingeführt. Hier ist eine Liste der wichtigsten Punkte des neuen Schalters :
  1. Durch die neue Syntax entfällt die Notwendigkeit einer break-Anweisung, um Fehler zu vermeiden.
  2. Switch-Ausdrücke schlagen nicht mehr fehl.
  3. Darüber hinaus können wir mehrere Konstanten in einem einzigen Label definieren.
  4. In Switch-Ausdrücken ist jetzt die Standard-Groß-/Kleinschreibung erforderlich.
  5. break wird in Switch-Ausdrücken verwendet, um Werte aus dem Register selbst zurückzugeben (tatsächlich kann ein Schalter Werte zurückgeben).
Schauen wir uns das als Beispiel an:
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
            break "Please insert a valid day.";
      else
            break "Looks like a Sunday.";
  }
};
Definitiver Leitfaden zum Wechseln von Ausdrücken in Java 13 Weitere neue Funktionen:
  1. String:

    transform(Function f)– Wendet die bereitgestellte Funktion auf eine Zeichenfolge an. Das Ergebnis ist möglicherweise keine Zeichenfolge.
    indent(int x)– fügt der Zeichenfolge x Leerzeichen hinzu. Wenn der Parameter negativ ist, wird diese Anzahl führender Leerzeichen entfernt (sofern möglich).

  2. Files- hat sich eine Methode wie geholt mismatch(), die wiederum die Position des ersten nicht übereinstimmenden Bytes im Inhalt von zwei Dateien findet und zurückgibt, oder -1L, wenn keine Nichtübereinstimmung vorliegt.

  3. Es ist eine neue Klasse erschienen –CompactNumberFormat zum Formatieren einer Dezimalzahl in kompakter Form. Ein Beispiel für diese kompakte Form ist 1M statt 1.000.000. Somit sind nur zwei statt neun Zeichen erforderlich.

  4. Es gibt auch eine neue enum , NumberFormatStyledie zwei Werte hat – LONG und SHORT.

  5. InputStream Habe die Methode skipNBytes(long n) : Überspringen Sie die n-te Anzahl von Bytes aus dem Eingabestream.

Interessante Java 12-Links:

Java 13

Die Welt steht nicht still, sie bewegt sich, sie entwickelt sich, genau wie Java – Java 13. Von 8 bis 13: eine vollständige Übersicht über die Java-Versionen.  Teil 2 - 3

Textblock

Java hat schon immer etwas gelitten, wenn es um die Definition von Strings geht. Wenn wir eine Zeile mit einem Leerzeichen, einem Zeilenumbruch, einem Anführungszeichen oder etwas anderem definieren müssen, verursachte dies einige Schwierigkeiten, sodass wir Sonderzeichen verwenden mussten: zum Beispiel \n für einen Zeilenumbruch oder einen Teil der Zeile mit Escapezeichen versehen selbst. Dies verringert die Lesbarkeit des Codes erheblich und nimmt beim Schreiben einer solchen Zeile zusätzliche Zeit in Anspruch. Dies macht sich besonders beim Schreiben von Zeichenfolgen bemerkbar, die JSON, XML, HTML usw. anzeigen. Wenn wir also ein kleines JSON schreiben möchten, sieht es in etwa so aus:
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
Und dann kommt Java 13 auf den Plan und bietet uns seine Lösung in Form von dreifachen doppelten Anführungszeichen vor und nach dem Text (die sie Textblöcke nannten). Schauen wir uns das vorherige JSON-Beispiel mit dieser Innovation an:
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
Viel einfacher und klarer, nicht wahr? Außerdem wurden jeweils Stringdrei neue Methoden zur Verwaltung dieser Blöcke hinzugefügt:
  • stripIndent(): Entfernt zufällige Leerzeichen aus einer Zeichenfolge. Dies ist nützlich, wenn Sie mehrzeilige Zeichenfolgen lesen und dieselbe Art von zufälligem Leerraumausschluss anwenden möchten, der bei einer expliziten Deklaration auftritt (wobei im Wesentlichen simuliert wird, dass der Compiler zufällige Leerzeichen entfernt).
  • formatted(Object... args ): ähnlich wie format(String format, Object... arg), aber für Textblöcke;
  • translateEscapes(): Gibt eine Zeichenfolge mit Escape-Sequenzen (z. B. \r) zurück, die in den entsprechenden Unicode-Wert übersetzt wurden.

Schalter verbessern

Switch-Ausdrücke wurden in Java 12 eingeführt und 13 verfeinert sie. In 12 definieren Sie Rückgabewerte mithilfe von break. In 13 wurde der Rückgabewert durch yield ersetzt. Jetzt kann der Schalterausdruck, den wir im Abschnitt Java 12 hatten, wie folgt umgeschrieben werden:
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
          yield "Please insert a valid day.";
      else
          yield "Looks like a Sunday.";
  }
};
Obwohl es für uns Programmierer, die bereits mit Java vertraut waren, normal war, Break zu akzeptieren, war es dennoch ziemlich seltsam. Was will mir Break True sagen? Das neue (relativ neue) Yield-Schlüsselwort ist klarer und könnte in Zukunft an anderen Stellen erscheinen, an denen Werte zurückgegeben werden. Für diejenigen, die sich stark für dieses Thema interessieren, empfehle ich Ihnen, sich mit diesen Materialien vertraut zu machen:

Dynamische CDS-Archive

CDS – Klassendatenaustausch. Ermöglicht das Packen einer Reihe häufig verwendeter Klassen in ein Archiv, das später von mehreren JVM-Instanzen geladen werden kann. Warum brauchen wir das? Tatsache ist, dass die JVM beim Laden von Klassen eine ganze Reihe ressourcenintensiver Aktionen ausführt, z. B. Klassen lesen, in internen Strukturen speichern, die Richtigkeit der gelesenen Klassen überprüfen, nach abhängigen Klassen suchen und diese laden usw ., und erst danach sind die Klassen einsatzbereit. Verständlicherweise werden viele Ressourcen verschwendet, da JVM-Instanzen häufig dieselben Klassen laden können. Zum Beispiel String, LinckedList, Integer. Nun, oder Klassen derselben Anwendung, und das alles sind Ressourcen. Wenn wir alle notwendigen Schritte nur einmal durchführen und dann die neu gestalteten Klassen in einem Archiv ablegen würden, das in den Speicher mehrerer JVMs geladen werden könnte, könnte dies erheblich Speicherplatz sparen und die Startzeit der Anwendung verkürzen. Tatsächlich ermöglicht CDS die Erstellung eines solchen Archivs. Java 9 erlaubte nur das Hinzufügen von Systemklassen zum Archiv. Java 10 – Anwendungsklassen in das Archiv aufnehmen. Die Erstellung eines solchen Archivs besteht aus:
  • Erstellen einer Liste der von der Anwendung geladenen Klassen;
  • Erstellen eines dringend benötigten Archivs mit den gefundenen Klassen.
Die Neuerung in Java 13 verbessert CDS, sodass es beim Beenden der Anwendung ein Archiv erstellen kann. Das bedeutet, dass die beiden oben genannten Schritte nun zu einem zusammengefasst werden. Und noch ein wichtiger Punkt: Nur Klassen, die während der Ausführung der Anwendung geladen wurden, werden dem Archiv hinzugefügt. Mit anderen Worten: Die Klassen, die noch in application.jar enthalten sind, aber aus irgendeinem Grund nicht geladen wurden, werden nicht zum Archiv hinzugefügt.

Aktualisieren Sie die Socket-API

Die Socket-API ( java.net.Socket und java.net.ServerSocket ) ist seit ihrer Einführung im Wesentlichen ein integraler Bestandteil von Java, aber Sockets wurden in den letzten zwanzig Jahren nie aktualisiert. Da sie in C und Java geschrieben waren, waren sie sehr, sehr umfangreich und schwer zu warten. Aber Java 13 hat beschlossen, in dieser ganzen Angelegenheit eigene Anpassungen vorzunehmen und die Basisimplementierung zu ersetzen. Anstelle von PlainSocketImpl wird die Anbieterschnittstelle nun durch NioSocketImpl ersetzt . Diese neue codierte Implementierung basiert auf derselben Back-End-Infrastruktur wie java.nio . Im Wesentlichen verwendet die Klasse den java.util.concurrent-Puffercache und den Sperrmechanismus (die segmentbasiert sind) anstelle synchronisierter Methoden. Es ist kein nativer Code mehr erforderlich, was die Portierung auf verschiedene Plattformen erleichtert. Dennoch haben wir eine Möglichkeit, zur Verwendung von PlainSocketImpl zurückzukehren , aber von nun an wird standardmäßig NioSocketImpl verwendet .

Speicherrückgabe für ZGC

Wie wir uns erinnern, wurde der Z-Garbage Collector in Java 11 als Garbage-Collection-Mechanismus mit geringer Latenz eingeführt, sodass die GC-Pause niemals 10 ms überschreitet. Aber gleichzeitig könnte es im Gegensatz zu anderen virtuellen GC-HotSpots wie Shenandoah und G1 ungenutzten dynamischen Speicher an das Betriebssystem zurückgeben. Diese Modifikation fügt ZGC diese J-Fähigkeit hinzu. Dementsprechend reduzieren wir den Speicherbedarf bei gleichzeitig verbesserter Leistung, und ZGC gibt nun standardmäßig nicht zugewiesenen Speicher an das Betriebssystem zurück, bis die angegebene minimale Heap-Größe erreicht ist. Noch etwas: ZGC hat jetzt eine maximal unterstützte Heap-Größe von 16 TB. Bisher waren 4 TB die Grenze. Weitere Neuerungen:
  1. javax.security– Eine Eigenschaft hinzugefügt, jdk.sasl.disabledMechanismsum SASL-Mechanismen zu deaktivieren.
  2. java.nio- Es wurde eine Methode hinzugefügt FileSystems.newFileSystem (Path, Map <String,?>), um jeweils eine neue Datei zu erstellen.
  3. Klassen java.niohaben jetzt absolute (im Gegensatz zu relativen) getund set-Methoden. Sie enthalten wie die abstrakte Basisklasse Buffereine Methode slice()zum Abrufen eines Teils des Puffers.
  4. javax.xml.parsersMethoden zum Instanziieren von DOM- und SAX-Fabriken hinzugefügt (mit Namespace-Unterstützung).
  5. Die Unicode-Unterstützung wurde auf Version 12.1 aktualisiert.
Interessante Links zu Java 13:

Ergebnisse

Wir könnten die angekündigten Neuerungen in Java 14 durchgehen, aber da es schon bald das Licht der Welt erblicken wird – die Veröffentlichung von JDK 14 ist für den 17. März 2020 geplant – wäre es am besten, unmittelbar nach der Veröffentlichung eine separate, vollständige Überprüfung davon durchzuführen . Ich möchte Sie auch darauf aufmerksam machen, dass es in anderen Programmiersprachen mit langen Pausen zwischen den Veröffentlichungen, wie z. B. Python 2–3, keine Kompatibilität gibt: Das heißt, wenn der Code in Python 2 geschrieben ist, werden Sie dies tun Ich muss hart daran arbeiten, es in 3 zu übersetzen. Java ist in dieser Hinsicht etwas Besonderes, da es extrem abwärtskompatibel ist. Das bedeutet, dass Ihr Java 5- oder 8-Programm garantiert auf einer virtuellen Java 8-13-Maschine läuft – mit ein paar Ausnahmen, über die Sie sich vorerst keine Sorgen machen müssen. Es ist klar, dass dies umgekehrt nicht funktioniert: Wenn Ihre Anwendung beispielsweise Java 13-Funktionen verwendet, die in der Java 8 JVM einfach nicht verfügbar sind. Das ist alles, was ich für heute habe, Respekt vor denen, die bis hierhin gelesen haben)) Von 8 bis 13: eine vollständige Übersicht über die Java-Versionen.  Teil 2 - 5
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION