L'edizione più recente di GraalVM è la GraalVM for JDK 22.0.1 (16 aprile 2024). È disponibile in due versioni: GraalVM per JDK 17, GraalVM per JDK 20.[2]
GraalVM presenta molteplici differenze rispetto ad una versione standard del JDK[3]:
GraalVM nasce dal progetto Maxine VM ai laboratori Sun Microsystems (tuttora Oracle Labs). Lo scopo era quello di scrivere una macchina virtuale Java attraverso Java stesso, con lo scopo di rimuovere dallo sviluppo software i problemi tipici di C++, in particolare la gestione manuale della memoria, e beneficiare di particolari ottimizzazioni.[4] Una volta realizzato che questo rappresentava un primo passo troppo ambizioso, fu presa la decisione di focalizzarsi solamente sul compilatore e collegarlo ad HotSpot, riutilizzando così il più possibile il runtime di HotSpot. Il compilatore GraalVM vede i suoi albori da una conversione manuale del codice client del compilatore HotSpot in Java (chiamato "C1"), rimpiazzando il precedente compilatore Maxine.[5]
Lo scopo generale del progetto è quindi diventato:
Aumentare le performance di linguaggi basati sulla Java VM per raggiungere i livelli di linguaggi nativi.[3][6]
Ridurre il tempo di avvio di applicazioni basate su JVM compilandole ahead-of-time attraverso la tecnologia GraalVM Native Image.[7]
Creare una piattaforma dove sia possibile combinare in maniera libera qualsiasi linguaggio di programmazione in un unico programma definito "programma poliglotta".[3][12]
Includere un insieme di strumenti per lo sviluppo software poliglotto facilmente estendibili.[3][13]
Graal è stato incluso all'interno delle versioni di macchine virtuali Java basate su HotSpot, come OpenJDK, da Java 9 fino a Java 15. Questo per supportare la compilazione sperimentale ahead-of-time. L'opzione UseJVMCICompiler permetteva inoltre di utilizzare JIT come rimpiazzo per C2.[14] Questa opzione è stata rimossa con Java 16 in quanto mantenere entrambe le versioni all'interno del JDK e nelle edizioni stand-alone di GraalVM avrebbe richiesto il doppio dello sforzo.[15] Una funzionalità simile per creare eseguibili nativi da progetti Java è permesso attraverso l'utilizzo dello strumento native-image di GraalVM.[7]
Edizioni
Oracle Corporation ha annunciato il rilascio di Oracle GraalVM Enterprise Edition l'8 Maggio 2019.[16] Fino al 2023, GraalVM era disponibile come versione Community Edition (CE) con licenza GPLv2 e come Oracle GraalVM Enterprise Edition (EE) accettando un appropriato contratto di licenza chiamato GraalVM Oracle Technology Network.[17] L'edizione Enterprise del prodotto, oltre ad avere aggiornamenti di sicurezza, possiede ulteriori funzionalità aggiuntive non a disposizione dell'edizione Community.[18]
A partire dal 2023, le nuove edizioni di GraalVM Community Edition (CE) seguiranno i rilasci ogni sei mesi del JDK.[19] Inoltre, il nome delle versioni sarà associato alla versione del JDK al quale GraalVM fa riferimento, ad esempio GraalVM per JDK 17. La versione GraalVM Enterprise Edition invece cambia nome e diventa Oracle GraalVM. Con questo cambiamento viene aggiornata anche la licenza che diventa GraalVM Free Terms and Conditions (GFTC).[20] Questa licenza permette gratuitamente di utilizzare Oracle GraalVM sia durante lo sviluppo che in ambienti commerciali a patto che i servizi costruiti con essa non vengano offerti a pagamento.[2]
GraalVM 23 (JDK 17 e 20)
Rilasciata il 13 giugno 2023, è la prima edizione di GraalVM ad abbandonare la nomenclatura tradizionale associata all'anno di pubblicazione (ad esempio, l'anno 2022 corrispondeva alle edizioni 22.x.x di GraalVM).[2] Sono infatti disponibili due edizioni, GraalVM per JDK 17.0.7 e JDK 20.0.1.[21][22] In questo periodo transitorio è comunque possibile riferirsi alla versione GraalVM 23.0.0.[23] Entrambe le versioni supportano il Garbage Collector ZGC per computazioni che richiedono una bassa latenza o un utilizzo dell'heap elevato. Inoltre, è stato reso open-source Ideal Graph Visualizer (IGV) per permettere agli sviluppatori di linguaggi terzi di utilizzarlo e contribuire al suo sviluppo.[24]
GraalVM 22
GraalVM 22.3: Rilasciata nel ottobre 2022.[25] Questa edizione include il supporto al JDK 19, in quanto nelle successive versioni di GraalVM, il supporto a JDK 11 verrà deprecato.[26]
GraalVM 22.2: Rilasciata nel luglio 2022. Con questa edizione il JDK GraalVM è diventato modulare per ridurre le dimensioni dello stesso.[27] I runtime di JavaScript, LLVM e VisualVM non sono più inclusi nel JDK ma possono essere installati nella stessa maniera di quelli relativi a Python, Native Image e Ruby. In questa edizione, il supporto ad Apple Silicon è compreso anche nella versione Enterprise di GraalVM.[28]
GraalVM 22.1: Rilasciata nel aprile 2022. È stata introdotta una nuova modalità di creazione delle native-image chiamata quick-build che riduce ulteriormente il tempo necessario per la generazione.[29] Inoltre è stato rilasciato, per la Community Edition, il supporto in modalità sperimentale per Apple Silicon con l'edizione darwin-aarch64. Per quanto riguarda Python è stato invece aggiunto il supporto ai moduli frozen, che permette di diminuire ulteriormente il tempo di esecuzione e l'impatto sulla memoria del sistema.[30]
GraalVM 22.0: Rilasciata nel gennaio 2022. In questa edizione è stato completamente rimosso il supporto a Java 8, da questa edizione verranno solamente supportati i JDK 11 e 17. Sono stati effettuati dei cambiamenti per ridurre la dimensione delle native-image.[31] Inoltre è stata migliorata la descrizione a terminale del processo di creazione delle native-image.[32]
GraalVM 21
GraalVM 21.2: Rilasciata il 20 luglio 2021. È stata rilasciata la versione ufficiale del plugin per native-image di Gradle e Maven, con un supporto sperimentale per JUnit 5. È stato aggiunto un supporto base per Java Flight Recorder (JFR) per JDK 11.[33]
GraalVM 21.1: Rilasciata il 20 aprile 2021. Aggiunge il supporto sperimentale a JDK 16 per entrambe le versioni Enterprise e Community. Con questa edizione Node.js non è più incluso nella versione base di GraalVM, può essere installato a parte tramite un appropriato comando.[34]
GraalVM 21.0: Rilasciata il 19 gennaio 2021. Con questa versione viene aggiunta l'esecuzione in modalità sperimentale di Java come linguaggio implementato da Truffle. Inoltre è stata aggiunta la possibilità di utilizzare la serializzazione di Java all'interno dei binari native-image.[35]
GraalVM 20
GraalVM 20.3: Rilasciata nel novembre 2020. Questa è la prima versione con supporto a lungo termine (LTS) Enterprise di GraalVM e l'ultima per l'anno 2020. Questa versione supporta la condivisione di codice nel runtime LLVM di GraalVM, permettendo all'Abstract Syntax Tree (AST) e al codice compilato del bitcode delle librerie condivise di essere condiviso tra diversi contesti all'interno di un unico sistema.[36]
GraalVM 20.1: Rilasciata a maggio 2020. Include molti miglioramenti per vari componenti. Oltre ad aumentare le performance generali del sistema, sono state aggiunte delle semplificazioni nell'utilizzo della native-image di GraalVM. Il motore interno di JavaScript supporta tutte le funzionalità di ECMAScript 2020 in maniera standard. Il motore di parsing di espressioni regolari (TRegex) usato da JavaScript e Python supporta ora tutte le espressioni. Inoltre è stata migliorata la compatibilità alle native gems all'interno di Ruby (TruffleRuby).[37]
GraalVM 20.0: Rilasciata a febbraio 2020. All'interno di questa release è stato migliorato il supporto a Windows. Inoltre, sono stati migliorati gli strumenti della native-image e i relativi tool di supporto, insieme a cambiamenti all'interno del compilatore e dei linguaggi supportati.[38]
GraalVM 19
GraalVM 19.0: Il supporto per Windows di questa versione è ancora in fase di sviluppo ed è rilasciato come funzionalità disponibile per gli early-adopters. GraalVM 19.0 è basata sulla versione JDK 8u212.[39]
Componenti
Il compilatore di GraalVM include i componenti di una normale macchina virtuale Java (in particolare OpenJDK). Alcuni componenti aggiuntivi sono inclusi in GraalVM per supportare le nuove modalità di esecuzione (GraalVM Native Image) o ulteriori linguaggi di programmazione come il runtime LLVM, GraalVM JavaScript (un potenziale rimpiazzo per il deprecato sistema Nashorn) e TRegex come sistema per espressioni regolari.[10][40][41]
Compilatore GraalVM
Il compilatore GraalVM è un moderno compilatore just-in-time scritto in Java. Si posiziona come complementare o, in alcuni casi come rimpiazzo, per i compilatori esistenti in HotSpot (C1/C2). In contrasto con i precedenti compilatori, il compilatore GraalVM è scritto in maniera modulare, mantenibile ed espandibile attraverso Java stesso.[42] Per permettere l'esecuzione di diversi linguaggi di programmazione all'interno della stessa JVM, il compilatore lavora con una rappresentazione intermedia (IR) comune dei linguaggi sotto forma di grafo. I passi eseguiti durante la compilazione sono i seguenti[43]:
Il codice e i dati (Albero sintattico astratto - AST) del framework Truffle sono valutati parzialmente per produrre un grafo di compilazione. Quando un AST è chiamato molte volte durante l'esecuzione del codice è programmato per essere messo in compilazione dal compilatore.
Il grafo di compilazione viene ottimizzato dal compilatore Graal per produrre codice macchina.
JVMCI installa questo codice macchina all'interno della cache di codice della VM.
L'AST ridirigerà automaticamente l'esecuzione verso il codice macchina installato in precedenza non appena questo sarà disponibile.
GraalVM Native Image è una tecnologia di compilazione ahead-of-time che produce dai file delle classi degli eseguibili binari. È stata originariamente rilasciata come un plugin per early adopter, che significa che il prodotto è pronto al rilascio ma potrebbe includere delle parti non compatibili con futuri aggiornamenti.[44]
Questa funzionalità supporta tutti i linguaggi basati sulla JVM, ma può, in maniera opzionale, eseguire linguaggi dinamici costruiti attraverso la piattaforma Truffle di GraalVM. Il file non viene eseguito all'interno della JVM e usa i componenti necessari del runtime come lo scheduling dei thread o il Garbage Collector (GC) da una versione minimale della JVM chiamata Substrate VM. Dato che i binari nativi così ottenuti includono le classi delle applicazioni, le dipendenze del JDK e le librerie, il tempo di avvio e di esecuzione sono fortemente ridotti.[44]
GraalVM Native Image è ufficialmente supportata dai framework Fn, Gluon, Helidon, Micronaut, Picocli, Quarkus, Vert.x e SpringBoot Java.[41][45] Nel Settembre 2016, Oracle ha comunicato i suoi piani per aggiungere la compilazione ahead-of-time all'interno di OpenJDK utilizzando il compilatore GraalVM per Java 9.[46][47] Questa proposta, identificata dal JEP 295 "Ahead-of-Time Compilation", è stata inclusa all'interno di Java 9. L'uso in fase sperimentale di GraalVM come compilatore just-in-time è stato aggiunto per la piattaforma Linux x86-64 per Java 10.[48]
Nelle versioni del JDK dalla 9 alla 15, il comando jaot crea una Native Image di un progetto.[14] La configurazione sperimentale -XX:+EnableJVMCIProduct permette di attivare l'utilizzo del Graal JIT.[49] Questa funzionalità è attualmente disponibile nel componente native-image della versione stand-alone di GraalVM.[49]
Piattaforma di implementazione linguaggi Truffle
Insieme a GraalVM, Oracle Labs ha sviluppato un interprete di linguaggio per AST, chiamato "Truffle". Questa piattaforma permette di implementare linguaggi sfruttando GraalVM.[50][51] Molteplici linguaggi sono stati implementati in Truffle, incluso un interprete C che afferma di essere veloce tanto quanto GCC e Clang.[52]
La piattaforma Truffle e le parti che dipendono da essa (GraalVM SDK) sono rilasciate con licenza Universal Permissive License v1, per incoraggiare l'uso della piattaforma per progetti che non vogliono essere legati dal copyright o altri diritti derivati.[53]
Supporto a strumenti di misurazione
Uno dei maggiori vantaggi dell'ecosistema di GraalVM è il fatto di possedere degli strumenti, indipendenti dal linguaggio, dinamici e direttamente integrati nella VM, per misurare le prestazioni in modo tale da diagnosticare errori e ottenere informazioni di log interne.[54][55]
L'installazione di base di GraalVM consente, grazie al supporto della VM, l'utilizzo di debugger, di profilatori, di visualizzatore di heap e altri tool completamente indipendenti dal linguaggio utilizzato.[13] GraalVM include inoltre un'implementazione del backend del protocollo di debugging remoto di Chrome Inspector.[56] Anche se originariamente ideato per debugging di codice JavaScript, può essere utilizzato per debuggare tutti i linguaggi di GraalVM direttamente dal proprio browser.[56]
Linguaggi e runtime aggiuntivi
GraalVM è sviluppato e permette di sviluppare nell'ecosistema di Java. Può eseguire applicazioni in tutti i linguaggi che compilano in un bytecode Java, come ad esempio: Java, Scala, Kotlin.[12]
Grazie al framework di implementazione linguaggi di Truffle sono stati supportati ulteriori linguaggi all'interno di GraalVM.
GraalVM JavaScript: un runtime aderente alle direttive ECMAScript 2021, con supporto per Node.js[57]
TruffleRuby: un'implementazione del linguaggio Ruby con un supporto preliminare a Ruby on Rails[58]
Il supporto per linguaggi aggiuntivi può essere implementato dagli utenti di GraalVM. Alcuni linguaggi di terze parti rilevanti sono: GrCUDA[63][64][65], SOMns[66], TruffleSqueak[67][68] e Yona[69].
Programmazione poliglotta
Uno dei vantaggi di GraalVM è la possibilità di scrivere applicazioni "poliglotte".[12] Questo significa che uno sviluppatore ha la possibilità di far interagire vari linguaggi di programmazione all'interno dello stesso codice sorgente, ottenendo di conseguenza i vantaggi caratteristici di ogni linguaggio. Tutto ciò è reso possibile grazie al framework di implementazione di linguaggi Truffle.[50]
Creazione di array
Partendo dall'implementazione di uno dei linguaggi presenti in GraalVM è possibile dichiarare array all'interno del codice sorgenti in altri linguaggi di programmazione. L'interazione tra il linguaggio "locale" e quello "estraneo" è automaticamente gestita da Truffle. Negli snippet di codice seguenti, tratti dal manuale di GraalVM, è possibile osservare come utilizzare la programmazione poliglotta:[12]
Con Truffle, è anche possibile lanciare funzioni scritte in diversi linguaggi di programmazione all'interno di una singola applicazione, ad esempio, in Java:
try(Contextcontext=Context.create()){Valuefunction=context.eval("python","lambda x: x + 1");assertfunction.canExecute();intx=function.execute(41).asInt();assertx==42;}
In questo snippet di codice stiamo creando una funzione definita in Python. Questa funzione non fa altro che incrementare di un'unità un valore per poi ritornarlo allo sviluppatore. Da Java, per sicurezza, chiediamo prima se la variabile function può eseguire attraverso la funzione canExecute(), per poi invocarla attraverso la funzione execute().[70]
Diffusione
GraalVM è adottato in vari scenari industriali, tra i quali:
Disney: utilizza la native-image per ridurre i tempi di cold-start di alcuni suoi servizi su AWS[71]
Facebook: utilizzato per accelerare applicativi di Apache Spark riducendo l'impatto sulla memoria e sull'utilizzo della CPU[72]
Twitter: utilizzato per velocizzare alcuni micro-servizi della piattaforma[73]
Goldman Sach: la multinazionale di investimenti bancari ha riscritto il suo linguaggio di programmazione Slang basandolo su GraalVM attraverso Truffle.[74]
^abcd(EN) Polyglot Programming, su web.archive.org, 23 ottobre 2020. URL consultato il 4 luglio 2023 (archiviato dall'url originale il 23 ottobre 2020).
^ab(EN) Tools Reference, su web.archive.org, 25 aprile 2019. URL consultato il 4 luglio 2023 (archiviato dall'url originale il 25 aprile 2019).
^ab(EN) OpenJDK: Graal, su openjdk.org. URL consultato il 4 luglio 2023.
^ab(EN) Christian Wimmer e Thomas Würthinger, Truffle: a self-optimizing runtime system, in Proceedings of the 3rd annual conference on Systems, programming, and applications: software for humanity, Association for Computing Machinery, 19 ottobre 2012, pp. 13–14, DOI:10.1145/2384716.2384723. URL consultato il 5 luglio 2023.