Understanding Android: JAVA e Compilatore JIT (Just in Time)

Diego Stamigni

Si apre la seconda parte di questo Understanding dedicato questa volta alla comprensione del compilatore JIT.

Nell’articolo precedente vi ho raccontato dell’architettura di Android e di un sistema che i Dev. hanno introdotto nella release Froyo (Android 2.2).

Il sistema in esame è il JIT ( Just-in-time → Appena-in-tempo ) che dovrebbe aver migliorare il funzionamento del sistema Android Froyo ( testato su HTC Nexus One ) di almeno il 450%.

Come può avvenire una cosa del genere ?

Innanzitutto, il sistema JIT non è una cosa nuova, bensì nacque nei primi anni ’80, denominata inizialmente compilazione dinamica ( che ora differisce in parte dal JIT ) , magari rendendo un po l’idea di ciò che fa. Questo tipo di building è stato ( e viene utilizzato ) addirittura dalla Microsoft™ nel suo .NET e nel 2005 la Macromedia Flash dichiarò di voler implementare il JIT (a partire dalla v8.5 ) per migliorare le performance delle sue applicazioni. Altri linguaggi quali il Lisp utilizzano tutt’oggi il concetto di compilazione dinamica.

Proprio in un sistema a compilazione dinamica (quale il Lisp), il compilatore può essere utilizzato in fase di esecuzione: il Lisp ha una funzione compile con cui è possibile compilare nuove funzioni create durante l’esecuzione. Sebbene sia vantaggiosa durante una sessione di debug interattivo, la compilazione dinamica risulta poco utile quando la fase di sviluppo del sistema è terminata.

Il sistema JIT agisce sul bytecode generato dal compilatore. Il bytecode non è nient’altro che una rappresentazione intermedia della trasformazione del codice sorgente, portabile ed ottimizzabile, che verrà poi interpretata da una Virtual Machine. Non appena è stato generato il bytecode, esso viene installato e successivamente il compilatore dell’ambiente di esecuzione lo traduce in codice macchina nativo; la traduzione in codice macchina può avvenire per file o per funzione: le funzioni possono essere compilate solo quando stanno per essere eseguite, da qui il nome just-in-time, ovvero “appena in tempo”. Il buon compromesso tra velocità d’esecuzione e portabilità del codice sta nel fatto che tutte le operazioni pesanti vengono effettuate in fase di building, perciò si ha un maggior tempo di compilazione: nella fase successiva alla compilazione del bytecode, cioè durante la trasformazione dello stesso in codice nativo, tutte quelle operazioni che richiedono molto tempo per essere eseguite, come l’analisi sintattica e semantica del codice sorgente e una prima fase di ottimizzazione vengono eseguite e quindi i tempi di esecuzione successivi sono stati snellitti e già semi-ottimizzati.

Ultimo appunto da fare riguarda i compilatori JIT sta sulla progettazione: essi sono chiaramente più semplici da scrivere poichè tutto il lavoro vero è affidato al compilatore che ha prodotto il bytecode.



Si conclude così la parte dell’Understanding dedicata all’architettura; avrei intenzione di scrivere qualche accenno riguardo una programmazione basilare di applicativi per Android. Che ne dite, vi potrebbe interessare ?

Scrivetene a riguardo nei commenti! 🙂

androidworld