Nota:

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:

Nota: Oracle Cloud Infrastructure (OCI) offre GraalVM Enterprise senza costi aggiuntivi.

Obiettivi laboratorio

In questo laboratorio:

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.

Accettazione codice VS

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.

Connessione nuovo tentativo codice VS

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:

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.

Terminale codice VS

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.

  1. 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, denominata benchmark-binary-tree.

  2. 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.

  1. 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.

  2. 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 strumento native-image in fase di compilazione.

  3. Dopo aver generato il file del profilo, creare la versione ottimizzata:

    mvn package -Poptimized
    

    Genera un file binario ottimizzato nella directory target, denominata benchmark-binary-tree-opt.

  4. 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ù

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.