Nota:
- Questa esercitazione è disponibile in un ambiente di esercitazione pratica gratuito fornito da Oracle.
- Utilizza valori di esempio per le credenziali, la tenancy e i compartimenti di Oracle Cloud Infrastructure. Al termine del laboratorio, sostituisci questi valori con quelli specifici del tuo ambiente cloud.
Ottimizza le applicazioni Java cloud native con GraalVM Enterprise PGO
Introduzione
In questo laboratorio viene illustrato come eseguire un benchmark JMH (Java Microbenchmark Harness) come eseguibile nativo, creato con GraalVM Native Image e applicato Profile-Guided Optimization (PGO) per migliorare le prestazioni.
GraalVM Native Image consente di compilare un'applicazione Java in un eseguibile nativo che inizia quasi istantaneamente e richiede meno memoria e CPU.
PGO (Profile-Guided Optimization) è una tecnica comunemente utilizzata nell'ecosistema Java per mitigare l'ottimizzazione just-in-time mancante e raccogliere i profili di esecuzione in un'unica esecuzione, quindi utilizzarli per ottimizzare le compilazioni successive. Con PGO è possibile raccogliere i dati di profilazione e quindi inserirli nello strumento native-image
, che utilizzerà queste informazioni per ottimizzare ulteriormente le prestazioni dell'eseguibile risultante.
Note sull'utilizzo di JMH con l'immagine nativa GraalVM
Quando viene eseguito sulla JVM, JMH forcherà una nuova JVM per ciascun benchmark per garantire che non vi siano interferenze nelle misurazioni per ciascun benchmark. Questo approccio non è possibile quando si utilizza GraalVM Native Image, pertanto è necessario prendere in considerazione le seguenti linee guida durante la creazione di benchmark JMH che devono essere eseguiti come eseguibili nativi:
- Includere un singolo benchmark in ogni eseguibile nativo
- Annotare il benchmark con
@Fork(0)
per assicurarsi che non venga forzato- Se si desidera creare un profilo per il benchmark per generare un benchmark ottimizzato, ignorare ovviamente i risultati del benchmark durante la creazione di profili
Nota: Oracle Cloud Infrastructure (OCI) offre GraalVM Enterprise senza costi aggiuntivi.
Obiettivi laboratorio
In questo laboratorio:
- Connessione a un host remoto in Oracle Cloud
- Compilare ed eseguire un benchmark JMH sulla JVM
- Creare questo benchmark JMH in un eseguibile nativo utilizzando l'immagine nativa GraalVM ed eseguirlo
- Ottimizza la versione eseguibile nativa con PGO ed eseguila
Tempo di laboratorio stimato: 30-45 minuti
NOTA: se nelle istruzioni viene visualizzata l'icona laptop, significa che è necessario immettere un comando. Tieni d'occhio questo.
# This is where we you will need to do something
Per copiare un comando, passare il mouse sul campo e fare clic sull'icona Copia negli Appunti.
Per incollare un comando copiato in una finestra del terminale, fare clic con il pulsante destro del mouse e selezionare l'opzione Incolla dal menu di scelta rapida. Se invece si preferiscono i tasti di scelta rapida, utilizzare CTRL+SHIFT+V
.
FASE 1: connessione a un host remoto e controllo dell'ambiente di sviluppo
L'ambiente di sviluppo viene fornito da un host remoto: un'istanza di computazione OCI con Oracle Linux 8, 4 CPU e 32 GB di memoria.
L'ambiente desktop verrà visualizzato prima che l'host remoto sia pronto, l'operazione può richiedere fino a due minuti.
Visual Studio Code (VS Code) verrà aperto e connesso automaticamente all'istanza VM di cui è stato eseguito il provisioning. Fare clic su Continua per accettare l'impronta digitale del computer.
Se non si fa clic su Continua, il codice VS verrà popup una finestra di dialogo, visualizzata di seguito. Fare clic su Nuovo tentativo. VS Code chiederà di accettare l'impronta digitale della macchina. Fare clic su Continua.
Problemi relativi alla connessione all'ambiente di sviluppo remoto
Se si verificano altri problemi durante i quali il codice VS non riesce a connettersi all'ambiente di sviluppo remoto non coperto sopra, provare quanto segue:
- Chiudi codice VS
- Fare doppio clic sull'icona "Luna-Lab.html" sul desktop
- Copiare lo "Configura script" dalla scheda Risorse e incollarlo di nuovo nel terminale desktop Luna
- Ripetere le istruzioni precedenti per connettersi all'ambiente di sviluppo remoto.
Congratulazioni, ora si è connessi a un host remoto in Oracle Cloud.
Lo script aprirà il codice VS, connesso all'host remoto, con il codice sorgente del laboratorio aperto.
Aprire quindi un terminale all'interno del codice VS. Il terminale consente di interagire con l'host remoto. È possibile aprire un terminale in Codice VS tramite il menu: Terminal > New Terminal (Nuovo terminale), come illustrato di seguito.
Nota sull'ambiente di sviluppo
Per questa esercitazione pratica utilizzerai GraalVM Enterprise come ambiente runtime Java. GraalVM è una distribuzione JDK altamente performante di Oracle basata su Oracle Java SE.
Il tuo ambiente di sviluppo è preconfigurato con gli strumenti GraalVM Enterprise e Native Image richiesti per questo laboratorio. È possibile controllare che eseguendo i comandi seguenti nel terminale:
java -version
native-image --version
È possibile andare al passo successivo.
FASE 2: compilare ed eseguire un benchmark JMH su JVM
Il codice sorgente per l'applicazione - benchmark JMH - è disponibile sull'host remoto. Il benchmark JMH proviene dal Computer Language Benchmarks Game. Crea strutture binarie - prima della raccolta di eventuali nodi dell'albero - utilizzando almeno il numero minimo di allocazioni.
Questo benchmark JMH utilizza la riflessione Java. Lo strumento native-image
opera sotto l'ipotesi "mondo chiuso" e non includerà elementi accessibili in modo riflessivo nell'eseguibile nativo, a meno che non venga fornita la configurazione necessaria al momento dell'installazione. Pertanto, per creare un eseguibile nativo di questo benchmark JMH, è necessario eseguire l'agente di trace per fornire la configurazione della riflessione a native-image
. Ciò è già stato fatto per risparmiare tempo e la configurazione generata è disponibile in src/main/resources/META-INF/native-image/. Per ulteriori informazioni sulla configurazione delle riflessioni, vedere Luna Lab su GraalVM Immagine nativa e riflessione.
Creare ed eseguire il benchmark come applicazione Java, eseguendo il comando riportato di seguito.
mvn clean package exec:exec
Si noti che nel file pom.xml sono disponibili istruzioni per disattivare in modo esplicito il compilatore JIT GraalVM utilizzando l'opzione -XX:-UseJVMCICompiler
. Ciò significa che il benchmark verrà eseguito utilizzando il compilatore JIT C2.
L'applicazione eseguirà il benchmark in tre iterazioni e visualizzerà i risultati nel terminale. Il completamento dell'esecuzione deve richiedere meno di quattro minuti. Il risultato finale è il più significativo. Si dovrebbe vedere qualcosa come:
Benchmark (binaryTreesN) Mode Cnt Score Error Units
BinaryTrees.bench 14 thrpt 3 180.819 ± 8.301 ops/s
È ora possibile andare al passo successivo.
FASE 3: creare ed eseguire un benchmark JMH come eseguibile nativo
Ora creare un eseguibile nativo utilizzando GraalVM Enterprise Native Image.
Il benchmark JMH viene creato con Maven e applica il pugin Maven per la creazione di immagini native GraalVM (aprire pom.xml per visualizzare la registrazione del plugin native-maven-plugin
). Il plugin indica quale file JAR deve passare a native-image
e quale dovrebbe essere la classe principale eseguibile.
-
Creare un eseguibile nativo. La build dovrebbe richiedere circa un minuto:
mvn package -Pnative
Il profilo
-Pnative
Maven attiva la creazione di un eseguibile nativo. Verrà generato un eseguibile nativo nella directory target, denominatabenchmark-binary-tree
. -
Eseguire quindi il benchmark come eseguibile nativo:
./target/benchmark-binary-tree
Di seguito sono riportati i risultati ottenuti con GraalVM Enterprise Native Image 22.2.0:
Benchmark (binaryTreesN) Mode Cnt Score Error Units BinaryTrees.bench 14 thrpt 3 174.135 ± 10.020 ops/s
I numeri eseguibili nativi possono essere simili o migliori rispetto all'opzione precedente (non nativa). I risultati variano in base all'hardware su cui si esegue lo stesso benchmark.
È ora possibile andare al passo successivo.
FASE 4: Ottimizza un eseguibile nativo con PGO ed esegui
Ottimizzare ora il file eseguibile nativo utilizzando PGO (Profile-Guided Optimization). Si tratta di un processo in due fasi. In primo luogo, creare una versione istruita dell'eseguibile nativo ed eseguirla per tracciarne l'esecuzione e raccogliere un profilo prestazioni. Al termine dell'esecuzione, il file del profilo verrà generato, default.iprof, nella directory root del progetto. Creare quindi un eseguibile ottimizzato contenente i dati del profilo sul benchmark ed eseguirlo.
La funzione PGO (Profile Guided Optimization) è disponibile con GraalVM Enterprise Edition.
-
Creare un eseguibile nativo con strumentazione passando il profilo
-Pinstrumented
Maven:mvn package -Pinstrumented
Genera un file binario nella directory target, denominata
benchmark-binary-tree-instr
. -
Eseguilo per raccogliere i profili di frequenza-esecuzione-codice:
./target/benchmark-binary-tree-instr
I profili raccolti da questa esecuzione vengono memorizzati nel file default.iprof della directory di lavoro corrente, se non viene specificato altro.
Nota: è possibile specificare dove raccogliere i profili durante l'esecuzione di un eseguibile nativo con strumentazione passando l'opzione
-XX:ProfilesDumpFile=YourFileName
in runtime. È anche possibile raccogliere più file di profilo, specificando nomi diversi e passarli allo strumentonative-image
in fase di compilazione. -
Dopo aver generato il file del profilo, creare la versione ottimizzata:
mvn package -Poptimized
Genera un file binario ottimizzato nella directory
target
, denominatabenchmark-binary-tree-opt
. -
Infine, eseguire l'eseguibile nativo ottimizzato:
./target/benchmark-binary-tree-opt
Di seguito sono riportati i risultati ottenuti con GraalVM Enterprise Native Image 22.2.0 sul computer host:
Benchmark (binaryTreesN) Mode Cnt Score Error Units
BinaryTrees.bench 14 thrpt 3 223.241 ± 3.578 ops/s
Il punteggio medio delle operazioni al secondo è aumentato da 180 in esecuzione come applicazione Java a 223 in esecuzione come eseguibile nativo ottimizzato. I risultati variano in base all'hardware su cui si esegue lo stesso benchmark.
Riepilogo
Questo laboratorio ha dimostrato come ottimizzare i file eseguibili nativi con l'ottimizzazione guidata dal profilo (PGO) per ottenere un throughput più elevato rispetto alla versione Java, pur preservando altri vantaggi: avvio istantaneo, utilizzo ridotto della CPU e della memoria. Con PGO puoi "addestrare" la tua applicazione per carichi di lavoro specifici e trasformarla in un file binario ottimizzato senza sacrificare alcuna performance.
Per saperne di più
- Luna Lab su GraalVM Immagine nativa e riflessione
- Luna Lab su GraalVM Strumenti di build nativi, per Maven
Congratulazioni. Questo laboratorio è stato completato.
Altre risorse di apprendimento
Esplora altri laboratori su docs.oracle.com/learn o accedi a contenuti di formazione gratuiti sul canale YouTube di Oracle Learning. Inoltre, visitare education.oracle.com/learning-explorer per diventare Explorer di Oracle Learning.
Per la documentazione sul prodotto, visitare il sito Oracle Help Center.
Optimize Cloud Native Java Applications with GraalVM Enterprise PGO
F75977-01
January 2023
Copyright © 2023, Oracle and/or its affiliates.