Dans cette entrée, la fonction de "[Native Image]" (https://www.graalvm.org/docs/reference-manual/native-image/) de GraalVM Utilisé pour réduire le temps de démarrage des programmes de la console Java.
Après avoir fait ceci et cela, le programme qui a pris environ 1 seconde pour démarrer sur la JVM avec les performances d'un ordinateur spécifique (équivalent à une micro instance d'OCI) est devenu binaire natif, et le démarrage est devenu environ 100 ms.
Comme ça, je l'ai présenté sous / opt. Au moment de la rédaction de cet article, 19.3.1 est la dernière version de 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
Utilisez l'outil GraalVM "gu" pour présenter l'outil pour Native Image.
sudo /opt/graalvm-ce-java8-19.3.1/bin//gu install native-image
Pour que native-image fonctionne, vous avez besoin d'un ensemble de boîtes à outils pour créer le binaire sur la plate-forme cible. Étant donné que cette entrée utilise CentOS7, installez les packages comme indiqué ci-dessous.
sudo yum install -y glibc-devel zlib-devel gcc
Le programme utilisé dans cette entrée est une simple calculatrice de console. Cliquez ici pour la version GitHub. https://github.com/hrkt/commandline-calculator/releases/tag/0.0.4
cd master
../gradlew :calculator-cli-without-spring:shadowJar
Ensuite, calculator-cli-without-spring / build / libs / calculator-cli-without-spring-0.0.1-SNAPSHOT-all.jar sera créé. Ce fichier Jar est nécessaire pour l'exécution en utilisant le plug-in "Gradle Shadow" qui rassemble la partie auto-fabriquée et le Jar qui a été utilisé pour la première fois. Il s'agit d'une collection de fichiers dans un seul fichier JAR. Le fichier JAR terminé faisait environ 760 Ko.
$ 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
Exécutez-le et essayez d'exécuter "1 + 1".
[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]$
À ce stade, vous pouvez voir qu'il a fallu environ 1,3 seconde pour démarrer le programme. Le temps est mesuré par la méthode suivante.
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));
Décompressez le fichier JAR créé ci-dessus et décompressez-le dans votre espace de travail.
cd calculator-cli-without-spring/build/libs
mkdir inside
cd inside
jar xvf ../calculator-cli-without-spring-0.0.1-SNAPSHOT-all.jar
Après cela, créez un répertoire pour obtenir des informations de profil à utiliser dans native-image.
mkdir -p META-INF/native-image
Exécutez comme un programme Java normal avant d'exécuter native-image. En travaillant avec l'agent, il collecte des informations qui ne peuvent pas être obtenues par analyse statique, telles que le type de réflexion utilisé pendant le fonctionnement et si la bibliothèque de JNI est utilisée.
/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
Lorsque vous exécutez "1 + 1 =" et entrez "q" pour quitter le programme de la même manière que décrit ci-dessus, les informations suivantes seront collectées.
[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
Construire. La signification de l'option est expliquée sur le site. ](Http://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
Cela prend du temps de l'ordre de quelques minutes. Attendons patiemment. L'environnement et le programme cible de cette entrée prendront environ 5 minutes.
[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
Déplaçons le binaire terminé. Commençons plusieurs fois pour voir à quoi cela ressemble. Vous pouvez voir qu'il peut être démarré à partir de la première moitié de la ms à 2 chiffres jusqu'à environ 100 ms au plus tard. Il démarre beaucoup plus rapidement que sur la 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
Commençons par vérifier le type.
[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
C'est juste un binaire ELF ordinaire. Quel type de bibliothèque utilisez-vous ...
[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)
J'utilise une bibliothèque très standard dans ma distribution Linux. Et la taille est ...
[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
Environ 10 Mo. Il a considérablement gonflé.
Cette entrée portait sur la tentative d'accélérer le lancement des programmes de console Java avec l'image native de GraalVM.
J'ai admiré "démarrer", mais gardez à l'esprit que cela ne mentionne pas la vitesse à laquelle il fonctionne continuellement après cela.
Pour utiliser JNI, le programme que j'écrivais, j'ai d'abord utilisé JNA comme je l'ai écrit dans Another entry, mais natif -image n'a pas pu être exécuté avec succès. GitHub avait également un échange tel que (L'utilisation de JNA dans une image native ne fonctionne pas # 673) [https://github.com/oracle/graal/issues/673].
Il semble que le côté Image native de GraalVM ne prend pas encore en charge la fonction utilisant JNA utilisée dans cette entrée.
Recommended Posts