Versuchen Sie, den Start von Java-Konsolenprogrammen mit dem nativen Image von GraalVM zu beschleunigen

Überblick

In diesem Eintrag die Funktion von "[Native Image]" (https://www.graalvm.org/docs/reference-manual/native-image/) von GraalVM Wird verwendet, um die Startzeit von Java-Konsolenprogrammen zu verkürzen.

Zusammenfassend

Nach diesem und jenem Vorgang wurde das Programm, dessen Start auf der JVM mit der Leistung eines bestimmten Computers (entspricht einer Mikroinstanz von OCI) etwa 1 Sekunde dauerte, nativ binär, und der Start betrug etwa 100 ms.

Angenommener Leser

Was du machen willst

Vorbereitung

Umgebung

Vorbereitung von Graal VM und nativem Image

So habe ich es unter / opt eingeführt. Zum Zeitpunkt des Schreibens dieses Eintrags ist 19.3.1 die neueste Version von GraalVM.

cd /opt
sudo curl -L -O https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.1/graalvm-ce-java8-linux-amd64-19.3.1.tar.gz
sudo tar zxvf graalvm-ce-java8-linux-amd64-19.3.1.tar.gz

Verwenden Sie das GraalVM-Tool "gu", um das Tool für Native Image vorzustellen.

sudo  /opt/graalvm-ce-java8-19.3.1/bin//gu install native-image

Damit das native Image funktioniert, benötigen Sie eine Reihe von Toolkits, um die Binärdatei auf der Zielplattform zu erstellen. Da dieser Eintrag CentOS7 verwendet, installieren Sie die Pakete wie unten gezeigt.

sudo yum install -y glibc-devel zlib-devel gcc

Bereiten Sie das Java-Zielprogramm vor

Das in diesem Eintrag verwendete Programm ist ein einfacher Konsolenrechner. Klicken Sie hier für die GitHub-Version. https://github.com/hrkt/commandline-calculator/releases/tag/0.0.4

cd master
../gradlew :calculator-cli-without-spring:shadowJar

Dann wird der Rechner-cli-ohne-Feder / build / libs / rechner-cli-ohne-Feder-0.0.1-SNAPSHOT-all.jar erstellt. Diese Jar-Datei ist für die Ausführung mit dem Plug-In "Gradle Shadow" erforderlich, das das selbst erstellte Teil und das Jar zusammenführt, das zum ersten Mal verwendet wurde. Es ist eine Sammlung von Dateien in einer JAR-Datei. Die fertige JAR-Datei war ungefähr 760 KB groß.

$ ls -la calculator-cli-without-spring/build/libs/calculator-cli-without-spring-0.0.1-SNAPSHOT-all.jar
-rw-rw-r--. 1 opc opc 757383 Jan 31 23:13 calculator-cli-without-spring/build/libs/calculator-cli-without-spring-0.0.1-SNAPSHOT-all.jar

Führen Sie es aus und versuchen Sie, "1 + 1" auszuführen.

[opc@instance-20200117-1627 commandline-calculator]$ java -jar calculator-cli-without-spring/build/libs/calculator-cli-without-spring-0.0.1-SNAPSHOT-all.jar
Calculator is running. Press ctrl-c to exit.(boot in 1272 msec.)
1+1=
1+1
=2
q
[opc@instance-20200117-1627 commandline-calculator]$

Zu diesem Zeitpunkt können Sie sehen, dass das Starten des Programms etwa 1,3 Sekunden dauerte. Die Zeit wird nach der folgenden Methode gemessen.

            RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
            long uptimeInMillis = runtimeMXBean.getUptime();
            terminal.writer().println(String.format("Calculator is running. Press ctrl-c to exit.(boot in %d msec.)",
                    uptimeInMillis));

Native Image erstellen

Vorbereitung

Wickeln Sie die oben erstellte JAR-Datei ab und entpacken Sie sie in Ihren Arbeitsbereich.

cd calculator-cli-without-spring/build/libs
mkdir inside
cd inside
jar xvf ../calculator-cli-without-spring-0.0.1-SNAPSHOT-all.jar

Erstellen Sie anschließend ein Verzeichnis, um Profilinformationen zur Verwendung in Native Image abzurufen.

mkdir -p META-INF/native-image

Laufzeitprofil abrufen

Führen Sie es als normales Java-Programm aus, bevor Sie das native Image ausführen. Durch die Zusammenarbeit mit dem Agenten werden Informationen gesammelt, die durch statische Analyse nicht erhalten werden können, z. B. welche Art von Reflexion während des Betriebs verwendet wird und ob die Bibliothek von JNI verwendet wird.

/opt/graalvm-ce-java8-19.3.1/bin/java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -cp . com.hrkt.commandlinecalculator.Main

Wenn Sie "1 + 1 =" ausführen und "q" eingeben, um das Programm auf die gleiche Weise wie oben beschrieben zu beenden, werden die folgenden Informationen gesammelt.

[opc@instance-20200117-1627 inside]$ ls -la META-INF/native-image/
total 16
drwxrwxr-x. 2 opc opc 109 Jan 31 23:15 .
drwxrwxr-x. 6 opc opc  88 Jan 31 23:15 ..
-rw-rw-r--. 1 opc opc 689 Jan 31 23:15 jni-config.json
-rw-rw-r--. 1 opc opc   4 Jan 31 23:15 proxy-config.json
-rw-rw-r--. 1 opc opc 366 Jan 31 23:15 reflect-config.json
-rw-rw-r--. 1 opc opc 472 Jan 31 23:15 resource-config.json

Erstellen Sie eine Binärdatei mit nativem Bild

Bauen. Die Bedeutung der Option wird auf der Website erläutert. ](Https://www.graalvm.org/docs/reference-manual/native-image/)

 /opt/graalvm-ce-java8-19.3.1/bin/native-image  --no-server --no-fallback  --report-unsupported-elements-at-runtime -cp . com.hrkt.commandlinecalculator.Main

Dies dauert in der Größenordnung von Minuten. Warten wir geduldig. Die Umgebung und das Zielprogramm für diesen Eintrag dauern ungefähr 5 Minuten.

[com.hrkt.commandlinecalculator.main:13836]    classlist:  11,879.57 ms
[com.hrkt.commandlinecalculator.main:13836]        (cap):   3,604.46 ms
[com.hrkt.commandlinecalculator.main:13836]        setup:   9,898.60 ms
[com.hrkt.commandlinecalculator.main:13836]   (typeflow):  36,059.72 ms
[com.hrkt.commandlinecalculator.main:13836]    (objects):  23,227.98 ms
[com.hrkt.commandlinecalculator.main:13836]   (features):   3,516.18 ms
[com.hrkt.commandlinecalculator.main:13836]     analysis:  63,682.08 ms
[com.hrkt.commandlinecalculator.main:13836]     (clinit):   1,281.12 ms
[com.hrkt.commandlinecalculator.main:13836]     universe:   3,092.99 ms
[com.hrkt.commandlinecalculator.main:13836]      (parse):  10,531.88 ms
[com.hrkt.commandlinecalculator.main:13836]     (inline):  28,108.04 ms
[com.hrkt.commandlinecalculator.main:13836]    (compile): 176,012.21 ms
[com.hrkt.commandlinecalculator.main:13836]      compile: 227,565.33 ms
[com.hrkt.commandlinecalculator.main:13836]        image:   6,261.29 ms
[com.hrkt.commandlinecalculator.main:13836]        write:   2,044.20 ms
[com.hrkt.commandlinecalculator.main:13836]      [total]: 326,546.79 ms

Lauf

Verschieben wir die fertige Binärdatei. Beginnen wir mehrmals damit, um zu sehen, wie es aussieht. Sie können sehen, dass es von der ersten Hälfte der zweistelligen ms bis spätestens etwa 100 ms gestartet werden kann. Es startet viel schneller als auf der JVM.

[opc@instance-20200117-1627 inside]$ ./com.hrkt.commandlinecalculator.main
Calculator is running. Press ctrl-c to exit.(boot in 66 msec.)
^C
[opc@instance-20200117-1627 inside]$ ./com.hrkt.commandlinecalculator.main
Calculator is running. Press ctrl-c to exit.(boot in 14 msec.)
^C
[opc@instance-20200117-1627 inside]$ ./com.hrkt.commandlinecalculator.main
Calculator is running. Press ctrl-c to exit.(boot in 16 msec.)
^C
[opc@instance-20200117-1627 inside]$ ./com.hrkt.commandlinecalculator.main
Calculator is running. Press ctrl-c to exit.(boot in 24 msec.)
^C
[opc@instance-20200117-1627 inside]$ ./com.hrkt.commandlinecalculator.main
Calculator is running. Press ctrl-c to exit.(boot in 131 msec.)
^C
[opc@instance-20200117-1627 inside]$ ./com.hrkt.commandlinecalculator.main
Calculator is running. Press ctrl-c to exit.(boot in 27 msec.)
^C

Lassen Sie uns die Binärdatei überprüfen.

Lassen Sie uns zuerst den Typ überprüfen.

[opc@instance-20200117-1627 inside]$ file com.hrkt.commandlinecalculator.main
com.hrkt.commandlinecalculator.main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=b5ce8429a80c97c4e12c87c516a8b24b59c64086, not stripped

Es ist nur eine gewöhnliche ELF-Binärdatei. Welche Art von Bibliothek benutzen Sie ...

[opc@instance-20200117-1627 inside]$ ldd com.hrkt.commandlinecalculator.main
        linux-vdso.so.1 =>  (0x00007fff5abf9000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f74c3bf7000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f74c39db000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f74c37d7000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f74c35c1000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f74c33b9000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f74c2feb000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f74c3ef9000)

Ich verwende eine sehr Standardbibliothek in meiner Linux-Distribution. Und die Größe ist ...

[opc@instance-20200117-1627 inside]$ ls -la com.hrkt.commandlinecalculator.main
-rwxrwxr-x. 1 opc opc 10066064 Feb  1 04:08 com.hrkt.commandlinecalculator.main

Über 10 MB. Es schwoll beträchtlich an.

Zusammenfassung

In diesem Eintrag wurde versucht, den Start von Java-Konsolenprogrammen mit dem nativen Image von GraalVM zu beschleunigen.

Ich habe nach oben geschaut, um zu starten, aber denke daran, dass es nicht die Geschwindigkeit erwähnt, mit der es danach kontinuierlich läuft.

Ergänzung

Um JNI, das Programm, das ich geschrieben habe, zu verwenden, habe ich zuerst JNA verwendet, wie ich es in Ein anderer Eintrag geschrieben habe, aber nativ -image konnte nicht erfolgreich ausgeführt werden. GitHub hatte auch einen Austausch wie (Die Verwendung von JNA in einem nativen Image funktioniert nicht # 673) [https://github.com/oracle/graal/issues/673].

Es scheint, dass die Native Image-Seite von GraalVM die in diesem Eintrag verwendete Funktion mit JNA noch nicht unterstützt.

Recommended Posts

Versuchen Sie, den Start von Java-Konsolenprogrammen mit dem nativen Image von GraalVM zu beschleunigen
Versuchen Sie, Ruby und Java in Dapr zu integrieren
Versuchen Sie, TCP / IP + NIO mit JAVA zu implementieren
Versuchen Sie, ein Java-Programm mit VS-Code zu debuggen
Versuchen Sie, mit Java eine Verbindung zu AzureCosmosDB Emulator for Docker herzustellen
Versuchen Sie, Java mit GraalVM in ein natives Modul zu integrieren
Java-Programm zum Ändern der Größe eines Fotos in ein Quadrat mit Rändern
[Anfänger] Versuchen Sie, mit Java ein einfaches RPG-Spiel zu erstellen ①
Java zum Spielen mit Function
Versuchen Sie eine DB-Verbindung mit Java
Versuchen Sie gRPC mit Java, Maven
Stellen Sie mit Java eine Verbindung zur Datenbank her
Stellen Sie mit Java eine Verbindung zu MySQL 8 her
Eingabe in die Java-Konsole
Java mit Ramen lernen [Teil 1]
[Java] Mit Arrays.asList () zu beachtende Punkte
Wagen Sie es, Kaggle mit Java herauszufordern (1)
[Rails] So beschleunigen Sie das Docker-Compose
Versuchen Sie es mit Redis mit Java (jar)
Ich habe versucht, mit Java zu interagieren
[Java] Versuchen Sie, mithilfe von Generika zu implementieren
Versuchen Sie, die öffentliche Java-Methode zu extrahieren
Versuchen Sie die bidirektionale Kommunikation mit gRPC Java
Versuchen Sie, Yuma in Java zu implementieren
Java, Arrays für Anfänger
Ich habe versucht, die Geschwindigkeit von Graal VM mit JMH zu messen und zu vergleichen
Wenn ich versuche, mich bei devise anzumelden, wird automatisch zu root_path umgeleitet