Hallo Habr! Angesichts der nicht ganz aktuellen Nachrichten über die Richtlinien von Oracle zur Java-Lizenzierung wird das Problem der Umstellung von Oracle-Versionen auf
OpenJDK immer akuter. Odanko bei OracleLabs macht seit langem eine sehr coole Sache namens
GraalVM , einen coolen
JIT- Compiler, der in Java geschrieben wurde, sowie eine Laufzeit zum Ausführen von Code in Sprachen wie JavaScript, Ruby, Python, C, C ++, Scala, Kotlin, R, Clojure. Beeindruckend, oder? Aber nicht über die Kühle der polyglotten Umgebung, möchte ich Ihnen sagen. Wir werden über die Schwierigkeiten sprechen, die neueste Grail-Baugruppe in das OpenJDK 11-Ökosystem zu integrieren, und ein bisschen über die Leistung, ziemlich viel ...
Zuerst war das Wort
Die Geschichte meiner Bekanntschaft mit
Graalvm begann 2017 beim
Joker . Dort sprach
Chris Seaton ausführlich über die Interna des Compilers und zeigte die Magie der
AOT- Kompilierung am Beispiel des nativen Bildes aus der Grail-Lieferung (dies ist ein Witz, der Ihren Java-Code in eine native Binärdatei kompiliert).
Nach diesem Bericht habe ich sehr lange trainiert, die native Binärdatei meines Haustierprojekts zu kompilieren, Krücken und Rechen zu setzen, um an allen Stellen Reflexion zu verdienen (sei es nicht in Ordnung!) Und schließlich auf ungelöste Probleme mit IO gestoßen (etwas) dort ist es nicht mit einem Tierpfleger losgegangen, jetzt weiß ich nicht mehr was). Spucke während du auf nativem Bild bist :-(
Jahr 2018, alle der gleiche Joker und der gleiche Graalvm in einem sehr detaillierten Bericht von Oleg Shelaev über AOT.
In Berichten und Präsentationen sieht alles so cool aus, und es liegt auch ein Haustierprojekt auf der CD ... es ist Zeit, das Terminal freizulegen, einen neuen Gral-Release-Kandidaten zu schwingen und in die Schlacht zu ziehen! Wir werden den Jit berühren.
Hallo Welt
Durch Berühren und Treten einer neuen kleinen JIT (zum Zeitpunkt des Schreibens dieses Artikels ist die Version
ce-1.0.0-rc14 ) verwenden wir das Beispiel eines Codes zum Testen der Leistung von der Website
https://graalvm.org - unserem ersten Beispiel.
Was macht ein Java-Projekt (sogar
Hello World ) ohne Build-System? Das ist richtig, nur der, auf dem Javac kochen lernt. Javak werden wir nicht lernen, um zu kochen, lassen Sie Maven Javak steuern.
Treffen Sie also pom.xml:
pom.xml<?xml version="1.0"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>my-app</name> <url>http://maven.apache.org</url> <properties> <java.version>11</java.version> <graalvm.version>1.0.0-rc14</graalvm.version> </properties> <profiles> <profile> <id>jdk11</id> <activation> <jdk>11</jdk> </activation> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.10</version> <executions> <execution> <id>copy</id> <phase>process-test-classes</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.mycompany.app.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> </profile> </profiles> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>${java.version}</release> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.graalvm.compiler</groupId> <artifactId>compiler</artifactId> <version>${graalvm.version}</version> </dependency> <dependency> <groupId>org.graalvm.truffle</groupId> <artifactId>truffle-api</artifactId> <version>${graalvm.version}</version> </dependency> <dependency> <groupId>org.graalvm.sdk</groupId> <artifactId>graal-sdk</artifactId> <version>${graalvm.version}</version> </dependency> <dependency> <groupId>org.graalvm.js</groupId> <artifactId>js</artifactId> <version>${graalvm.version}</version> </dependency> <dependency> <groupId>org.graalvm.js</groupId> <artifactId>js-scriptengine</artifactId> <version>${graalvm.version}</version> </dependency> </dependencies> </project>
Die Struktur der Projektdatei sieht folgendermaßen aus:
Klassencode com.mycompany.app.App (Beispiel zum Kopieren und Einfügen von graalvm.org):
App.java package com.mycompany.app; public class App { static final int ITERATIONS = Math.max(Integer.getInteger("iterations", 1), 1); public static void main(String[] args) { String sentence = String.join(" ", args); for (int iter = 0; iter < ITERATIONS; iter++) { if (ITERATIONS != 1) System.out.println("-- iteration " + (iter + 1) + " --"); long total = 0, start = System.currentTimeMillis(), last = start; for (int i = 1; i < 10_000_000; i++) { total += sentence.chars().filter(Character::isUpperCase).count(); if (i % 1_000_000 == 0) { long now = System.currentTimeMillis(); System.out.printf("%d (%d ms)%n", i / 1_000_000, now - last); last = now; } } System.out.printf("total: %d (%d ms)%n", total, System.currentTimeMillis() - start); } } }
Code
module-info.java :
module-info.java module com.mycompany.app {}
Hmm, leer ... Aber es ist leer aus dem Grund, dass ich Ihnen zeigen möchte, wie benutzerdefiniertes Java (über benutzerdefiniertes Java etwas später) mit nicht deklarierten Modulen schwört, die unsere Anwendung benötigt.
Der erste Pfannkuchen ...
nicht klumpig. Lassen Sie uns unser Projekt zusammenstellen und starten. Um es so auszudrücken:
mvn clean package
Wir starten:
$JAVA_HOME/bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler -Diterations=10 -jar target/my-app-1.0-SNAPSHOT.jar In 2017 I would like to run ALL languages in one VM.
Hier gibt es zwei wichtige Punkte:
JVMCI ist eine experimentelle Sache, die seit Version 9 in Java
aufgetaucht ist. Wir brauchen also:
Ergebnis starten- Iteration 1 - 1 (1466 ms)
2 (461 ms)
3 (463 ms)
4 (138 ms)
5 (151 ms)
6 (159 ms)
7 (266 ms)
8 (128 ms)
9 (144 ms)
Gesamt: 69999993 (3481 ms)
- Iteration 2 - 1 (233 ms)
2 (169 ms)
3 (121 ms)
4 (205 ms)
5 (170 ms)
6 (152 ms)
7 (227 ms)
8 (158 ms)
9 (108 ms)
Gesamt: 69999993 (1644 ms)
- Iteration 3 - 1 (98 ms)
2 (102 ms)
3 (98 ms)
4 (102 ms)
5 (95 ms)
6 (96 ms)
7 (101 ms)
8 (95 ms)
9 (97 ms)
Gesamt: 69999993 (990 ms)
- Iteration 4 - 1 (109 ms)
2 (114 ms)
3 (97 ms)
4 (98 ms)
5 (100 ms)
6 (103 ms)
7 (125 ms)
8 (108 ms)
9 (100 ms)
Gesamt: 69999993 (1056 ms)
- Iteration 5 - 1 (98 ms)
2 (100 ms)
3 (105 ms)
4 (97 ms)
5 (95 ms)
6 (99 ms)
7 (95 ms)
8 (123 ms)
9 (98 ms)
Gesamt: 69999993 (1010 ms)
- Iteration 6 - 1 (99 ms)
2 (95 ms)
3 (102 ms)
4 (99 ms)
5 (96 ms)
6 (100 ms)
7 (99 ms)
8 (99 ms)
9 (104 ms)
Gesamt: 69999993 (993 ms)
- Iteration 7-1 (100 ms)
2 (104 ms)
3 (95 ms)
4 (96 ms)
5 (97 ms)
6 (95 ms)
7 (94 ms)
8 (108 ms)
9 (108 ms)
Gesamt: 69999993 (1000 ms)
- Iteration 8 - 1 (100 ms)
2 (106 ms)
3 (99 ms)
4 (95 ms)
5 (97 ms)
6 (97 ms)
7 (101 ms)
8 (99 ms)
9 (101 ms)
Gesamt: 69999993 (1012 ms)
- Iteration 9-1 (105 ms)
2 (97 ms)
3 (98 ms)
4 (96 ms)
5 (99 ms)
6 (96 ms)
7 (94 ms)
8 (98 ms)
9 (105 ms)
Gesamt: 69999993 (993 ms)
- Iteration 10-1 (107 ms)
2 (98 ms)
3 (99 ms)
4 (100 ms)
5 (97 ms)
6 (101 ms)
7 (98 ms)
8 (103 ms)
9 (105 ms)
Gesamt: 69999993 (1006 ms)
Was sehen wir hier? Und wir sehen, dass die erste Iteration die längste ist (3,5 Sekunden), diese JIT erwärmt sich. Und dann ist alles mehr oder weniger glatt (innerhalb einer Sekunde).
Aber was ist, wenn wir Java eine neue Version des Grals geben? Kaum gesagt als getan:
java -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler -Diterations=10 --module-path=target/lib --upgrade-module-path=target/lib/compiler-1.0.0-rc14.jar -jar target/my-app-1.0-SNAPSHOT.jar In 2017 I would like to run ALL languages in one VM.
Frisches Gral-Startergebnis- Iteration 1 - 1 (1789 ms)
2 (547 ms)
3 (313 ms)
4 (87 ms)
5 (88 ms)
6 (87 ms)
7 (83 ms)
8 (92 ms)
9 (87 ms)
Gesamt: 69999993 (3259 ms)
- Iteration 2 - 1 (241 ms)
2 (161 ms)
3 (152 ms)
4 (195 ms)
5 (136 ms)
6 (129 ms)
7 (154 ms)
8 (176 ms)
9 (109 ms)
Gesamt: 69999993 (1553 ms)
- Iteration 3 - 1 (109 ms)
2 (103 ms)
3 (113 ms)
4 (172 ms)
5 (141 ms)
6 (148 ms)
7 (111 ms)
8 (102 ms)
9 (101 ms)
Gesamt: 69999993 (1211 ms)
- Iteration 4 - 1 (96 ms)
2 (96 ms)
3 (104 ms)
4 (98 ms)
5 (96 ms)
6 (97 ms)
7 (98 ms)
8 (96 ms)
9 (95 ms)
Gesamt: 69999993 (972 ms)
- Iteration 5 - 1 (97 ms)
2 (93 ms)
3 (99 ms)
4 (97 ms)
5 (97 ms)
6 (97 ms)
7 (95 ms)
8 (98 ms)
9 (94 ms)
Gesamt: 69999993 (965 ms)
- Iteration 6 - 1 (96 ms)
2 (95 ms)
3 (96 ms)
4 (99 ms)
5 (102 ms)
6 (94 ms)
7 (99 ms)
8 (115 ms)
9 (109 ms)
Gesamt: 69999993 (1001 ms)
- Iteration 7-1 (98 ms)
2 (96 ms)
3 (99 ms)
4 (98 ms)
5 (118 ms)
6 (98 ms)
7 (95 ms)
8 (99 ms)
9 (116 ms)
Gesamt: 69999993 (1017 ms)
- Iteration 8-1 (95 ms)
2 (99 ms)
3 (99 ms)
4 (106 ms)
5 (101 ms)
6 (101 ms)
7 (93 ms)
8 (97 ms)
9 (108 ms)
Gesamt: 69999993 (993 ms)
- Iteration 9-1 (102 ms)
2 (95 ms)
3 (97 ms)
4 (125 ms)
5 (94 ms)
6 (101 ms)
7 (100 ms)
8 (95 ms)
9 (96 ms)
Gesamt: 69999993 (1008 ms)
- Iteration 10-1 (97 ms)
2 (97 ms)
3 (99 ms)
4 (112 ms)
5 (102 ms)
6 (96 ms)
7 (96 ms)
8 (98 ms)
9 (96 ms)
Gesamt: 69999993 (988 ms)
Das Ergebnis ist, wie wir sehen, nicht viel anders.
Ich habe es vergessen Nun, wir haben nicht versucht, dasselbe ohne den neuen JIT-Compiler auszuführen. Wir werden tun:
java -Diterations=10 -jar target/my-app-1.0-SNAPSHOT.jar In 2017 I would like to run ALL languages in one VM.
Ergebnis ohne einen neuen JIT-Compiler- Iteration 1 - 1 (372 ms)
2 (271 ms)
3 (337 ms)
4 (391 ms)
5 (328 ms)
6 (273 ms)
7 (239 ms)
8 (271 ms)
9 (250 ms)
Gesamt: 69999993 (2978 ms)
- Iteration 2 - 1 (242 ms)
2 (253 ms)
3 (253 ms)
4 (240 ms)
5 (245 ms)
6 (275 ms)
7 (273 ms)
8 (263 ms)
9 (234 ms)
Gesamt: 69999993 (2533 ms)
- Iteration 3 - 1 (237 ms)
2 (235 ms)
3 (234 ms)
4 (246 ms)
5 (242 ms)
6 (238 ms)
7 (244 ms)
8 (243 ms)
9 (253 ms)
Gesamt: 69999993 (2414 ms)
- Iteration 4 - 1 (244 ms)
2 (249 ms)
3 (245 ms)
4 (243 ms)
5 (232 ms)
6 (256 ms)
7 (321 ms)
8 (303 ms)
9 (249 ms)
Gesamt: 69999993 (2599 ms)
- Iteration 5 - 1 (246 ms)
2 (242 ms)
3 (248 ms)
4 (256 ms)
5 (280 ms)
6 (233 ms)
7 (235 ms)
8 (266 ms)
9 (246 ms)
Gesamt: 69999993 (2511 ms)
- Iteration 6 - 1 (292 ms)
2 (368 ms)
3 (339 ms)
4 (251 ms)
5 (267 ms)
6 (259 ms)
7 (289 ms)
8 (262 ms)
9 (357 ms)
Gesamt: 69999993 (3058 ms)
- Iteration 7-1 (284 ms)
2 (258 ms)
3 (248 ms)
4 (247 ms)
5 (266 ms)
6 (247 ms)
7 (242 ms)
8 (314 ms)
9 (265 ms)
Gesamt: 69999993 (2656 ms)
- Iteration 8-1 (239 ms)
2 (238 ms)
3 (257 ms)
4 (282 ms)
5 (244 ms)
6 (261 ms)
7 (253 ms)
8 (295 ms)
9 (256 ms)
Gesamt: 69999993 (2575 ms)
- Iteration 9-1 (273 ms)
2 (243 ms)
3 (239 ms)
4 (240 ms)
5 (250 ms)
6 (285 ms)
7 (266 ms)
8 (285 ms)
9 (264 ms)
Gesamt: 69999993 (2617 ms)
- Iteration 10-1 (245 ms)
2 (264 ms)
3 (258 ms)
4 (253 ms)
5 (239 ms)
6 (260 ms)
7 (251 ms)
8 (250 ms)
9 (256 ms)
Gesamt: 69999993 (2538 ms)
Das Ergebnis ist anders und anständig.
C2 bietet keine Optimierungen in heißen Codeteilen - jede Iteration mit derselben Zeit.
Graal ist in der Lage, heiße Codeteile zu optimieren und sorgt auf lange Sicht für eine gute Leistungssteigerung.
Um was?
Dies ist vielleicht die Hauptfrage, die Sie sich und anderen (Teammitgliedern) stellen müssen, wenn wir dem Projekt eine neue Funktion, ein neues Tool, eine neue virtuelle Maschine, eine neue JIT hinzufügen möchten ...
Meine Geschichte, wie sie oben geschrieben wurde, begann mit Joker 2017, dann gab es lange Versuche, AOT zu beherrschen, und jetzt probiere ich die Freuden von JIT für Java in Java.
Ein Haustierprojekt auf der Festplatte ist eine Art Geschäftsprozess-Engine, bei der Prozesse von Anwendungsentwicklern in der Browser-Benutzeroberfläche gezeichnet werden und Skripte in JS schreiben können, die auf der JVM ausgeführt werden.
In zukünftigen Versionen von Java versprechen sie, Nashorn zu entfernen, GraalVM nähert sich allmählich der Veröffentlichung ...
Die Antwort auf die Frage lautet:
- Wir möchten, dass eine Laufzeit JS ausführt (und nicht nur)
- will Geschwindigkeit jit
- Wir möchten, dass der Start von Pet-Project-Anwendungen wie zuvor auf 8-ke (ohne) angezeigt wird
- Modulpfad
und --upgrade-module-path
aber mit einer frischen Gralsanordnung)
Jlink
Die ersten beiden Punkte in der Liste der Antworten auf die obige Frage sind klar genug, lassen Sie uns letztere behandeln.
Tatsache ist, dass Entwickler-Administratoren-Entwickler faul sind und keine zusätzliche Arbeit erledigen möchten (das gefällt mir auch). Sie versuchen, alles zu automatisieren und in ein vorgefertigtes Bundle zu packen, das als einfaches Binärprogramm ausgeführt werden kann. Nun, es gibt ein Problem, lassen Sie es uns lösen.
Ein relativ neues Tool aus der Welt von Java 9+
hilft uns und heißt
jlink . Wir versuchen, unsere Anwendung mit allen erforderlichen Bibliotheken in einem Bundle zu packen:
jlink --module-path target/classes:target/lib:$JAVA_HOME/jmods --add-modules com.mycompany.app --launcher app=com.mycompany.app/com.mycompany.app.App --compress 2 --no-header-files --no-man-pages --strip-debug --output test
Wie viele Parameter von allen beschreiben wir die wichtigsten:
--module-path target / classes: target / lib: $ JAVA_HOME / jmods
--add-modules com.mycompany.app
--launcher app = com.mycompany.app / com.mycompany.app.App
- Ausgangstest
Sie können den Onkel von Google nach anderen Parametern fragen, die alle darauf abzielen, die Gesamtgröße des Bundles zu reduzieren.
Schauen wir uns das Ergebnis an:

In test / bin / app gibt es ein einfaches sh-Skript, das unsere Anwendung auf Java startet, das sich neben der App befindet:
Führen Sie
test / bin / app auf C2 aus:
./test/bin/app In 2017 I would like to run ALL languages in one VM.
Ergebnis- Iteration 1 - 1 (315 ms)
2 (231 ms)
3 (214 ms)
4 (297 ms)
5 (257 ms)
6 (211 ms)
7 (217 ms)
8 (245 ms)
9 (222 ms)
Gesamt: 69999993 (2424 ms)
- Iteration 2 - 1 (215 ms)
2 (215 ms)
3 (223 ms)
4 (224 ms)
5 (217 ms)
6 (208 ms)
7 (208 ms)
8 (222 ms)
9 (222 ms)
Gesamt: 69999993 (2164 ms)
- Iteration 3 - 1 (206 ms)
2 (226 ms)
3 (234 ms)
4 (211 ms)
5 (212 ms)
6 (213 ms)
7 (210 ms)
8 (245 ms)
9 (223 ms)
Gesamt: 69999993 (2216 ms)
- Iteration 4 - 1 (222 ms)
2 (233 ms)
3 (220 ms)
4 (222 ms)
5 (221 ms)
6 (219 ms)
7 (222 ms)
8 (216 ms)
9 (220 ms)
Gesamt: 69999993 (2215 ms)
- Iteration 5 - 1 (231 ms)
2 (230 ms)
3 (221 ms)
4 (226 ms)
5 (227 ms)
6 (223 ms)
7 (215 ms)
8 (216 ms)
9 (219 ms)
Gesamt: 69999993 (2234 ms)
- Iteration 6-1 (227 ms)
2 (218 ms)
3 (221 ms)
4 (254 ms)
5 (222 ms)
6 (212 ms)
7 (214 ms)
8 (222 ms)
9 (222 ms)
Gesamt: 69999993 (2241 ms)
- Iteration 7-1 (217 ms)
2 (225 ms)
3 (222 ms)
4 (223 ms)
5 (227 ms)
6 (221 ms)
7 (219 ms)
8 (226 ms)
9 (219 ms)
Gesamt: 69999993 (2217 ms)
- Iteration 8-1 (218 ms)
2 (242 ms)
3 (219 ms)
4 (218 ms)
5 (224 ms)
6 (226 ms)
7 (223 ms)
8 (220 ms)
9 (219 ms)
Gesamt: 69999993 (2228 ms)
- Iteration 9-1 (234 ms)
2 (218 ms)
3 (217 ms)
4 (217 ms)
5 (225 ms)
6 (222 ms)
7 (216 ms)
8 (226 ms)
9 (214 ms)
Gesamt: 69999993 (2212 ms)
- Iteration 10-1 (226 ms)
2 (230 ms)
3 (215 ms)
4 (238 ms)
5 (225 ms)
6 (218 ms)
7 (218 ms)
8 (215 ms)
9 (228 ms)
Gesamt: 69999993 (2233 ms)
Jetzt auf graalvm (indem Sie die erforderlichen Flags definieren, die in der Variablen
JLINK_VM_OPTIONS ausgeführt werden sollen):
Ergebnis:
Error occurred during initialization of boot layer java.lang.module.FindException: Module jdk.internal.vm.ci not found
Nun, wir sind gesegelt ... Und jetzt erinnern wir uns, dass wir mit Java 11 in einer modularen Umgebung arbeiten. Wir erstellen die Anwendung als Modul, aber sie haben niemandem von den verwendeten Modulen erzählt. Es ist Zeit, das Problem zu beheben.
Neue Version von module-info.java:
module com.mycompany.app { requires jdk.internal.vm.compiler; requires org.graalvm.sdk; requires org.graalvm.truffle; requires transitive org.graalvm.js; requires transitive org.graalvm.js.scriptengine; }
Wir sammeln , löschen das Testverzeichnis,
Link .
Ergebnis:
Error: automatic module cannot be used with jlink: icu4j from file:///home/slava/JavaProjects/graal-js-jdk11-maven-demo/target/lib/icu4j-62.1.jar
Was für ein "automatisches Modul kennote bi uzd"? Und dieser
jlink sagt uns, dass die icu4j
lib keine module-info.class enthält. Was ist erforderlich, damit eine solche Klasse in der angegebenen Bibliothek angezeigt wird:
- Verstehen Sie die Liste der von jedem verwendeten Module und erstellen Sie module-info.java . Definieren Sie alle Pakete, die von außen sichtbar sein sollen
- kompiliere module-info.java für
- Setze das kompilierte Modul-info.java mit any in die dzharnik ein
Lass uns gehen!
Die Datei module-info.java mit ihrem gesamten Inhalt generiert das Dienstprogramm jdeps aus openjdk-11 für uns:

Wir kompilieren module-info.java für icu4j:

Wir aktualisieren die dzharnik, indem wir
module-info.class hineinschieben :
$JAVA_HOME/bin/jar uf target/lib/icu4j-62.1.jar -C target/modules module-info.class
Verknüpfen ,
ausführen .
Ergebnis- Iteration 1 - 1 (1216 ms)
2 (223 ms)
3 (394 ms)
4 (138 ms)
5 (116 ms)
6 (102 ms)
7 (120 ms)
8 (106 ms)
9 (110 ms)
Gesamt: 69999993 (2619 ms)
- Iteration 2 - 1 (166 ms)
2 (133 ms)
3 (142 ms)
4 (157 ms)
5 (119 ms)
6 (134 ms)
7 (153 ms)
8 (95 ms)
9 (85 ms)
Gesamt: 69999993 (1269 ms)
- Iteration 3 - 1 (86 ms)
2 (81 ms)
3 (87 ms)
4 (83 ms)
5 (85 ms)
6 (100 ms)
7 (87 ms)
8 (83 ms)
9 (85 ms)
Gesamt: 69999993 (887 ms)
- Iteration 4 - 1 (84 ms)
2 (86 ms)
3 (88 ms)
4 (91 ms)
5 (85 ms)
6 (88 ms)
7 (87 ms)
8 (85 ms)
9 (85 ms)
Gesamt: 69999993 (864 ms)
- Iteration 5 - 1 (94 ms)
2 (86 ms)
3 (84 ms)
4 (83 ms)
5 (85 ms)
6 (86 ms)
7 (84 ms)
8 (84 ms)
9 (83 ms)
Gesamt: 69999993 (854 ms)
- Iteration 6 - 1 (83 ms)
2 (89 ms)
3 (87 ms)
4 (87 ms)
5 (86 ms)
6 (86 ms)
7 (91 ms)
8 (86 ms)
9 (85 ms)
Gesamt: 69999993 (865 ms)
- Iteration 7-1 (87 ms)
2 (86 ms)
3 (88 ms)
4 (90 ms)
5 (91 ms)
6 (87 ms)
7 (85 ms)
8 (85 ms)
9 (86 ms)
Gesamt: 69999993 (868 ms)
- Iteration 8-1 (84 ms)
2 (85 ms)
3 (86 ms)
4 (84 ms)
5 (84 ms)
6 (88 ms)
7 (85 ms)
8 (86 ms)
9 (86 ms)
Gesamt: 69999993 (852 ms)
- Iteration 9-1 (83 ms)
2 (85 ms)
3 (84 ms)
4 (85 ms)
5 (89 ms)
6 (85 ms)
7 (88 ms)
8 (86 ms)
9 (83 ms)
Gesamt: 69999993 (850 ms)
- Iteration 10-1 (83 ms)
2 (84 ms)
3 (83 ms)
4 (82 ms)
5 (85 ms)
6 (83 ms)
7 (84 ms)
8 (94 ms)
9 (93 ms)
Gesamt: 69999993 (856 ms)
Hurra! Wir haben es geschafft! Jetzt haben wir eine gesperrte Anwendung in Form eines laufenden Sh-Skripts mit unserem Java, mit allen notwendigen Modulen (einschließlich frischem Graalvm), mit Präferenz und jungen Damen.
PS
Java langweilt sich nicht und gibt dem Geist mit jeder Veröffentlichung neues Essen. Probieren Sie neue Funktionen aus, experimentieren Sie und tauschen Sie Erfahrungen aus. Ich hoffe, ich schreibe bald einen Artikel darüber, wie ich einen Teil des Haustierprojekts mit dem Gral verboten habe (dort werden vert.x, Asynchronismus und js-Skripte interessant sein).
Und doch ... das ist mein erster Artikel über Habré - bitte nicht hart treffen.