|
Heap & Heap Manager
L'Heap è l'aria di memoria delle Macchina Astratta dove vengono creati i
vari oggetti durante l'esecuzione di un programma in linguaggio Object-Oriented.
Si tratta di un'area accessibile da tutti i metodi ( contrariamente ai singoli
Stack Frame che sono locali ad ogni invocazione di metodi ), purché
tali metodi abbiano un riferimento ad un oggetto all'interno dell'Heap.
La componente che si occupa della gestione dell'Heap è
l'Heap Manager: ogni azione a Run-Time sugli oggetti
avviene sotto il suo controllo. Esso è responsabile della
creazione di nuove istanze di una classe: l'interprete gli fornisce
un puntatore ad una Class Structure ( ottenuto tramite il
Class Manager ), e l'Heap Manager lo userà per risalire
alla sezione della Class Structure ( la Field Table ) in cui è
specificato l'insieme di campi che ogni nuova istanza deve avere.
A questo punto l'Heap Manager alloca sull'Heap una porzione di memoria con la stessa
conformazione indicata dalla Field Table, e restituisce all'interprete
un riferimento all'area appena allocata.
Prima di restituire tale puntatore, l'Heap Manager compie alcune azioni per ragioni
di carattere organizzativo. Una di queste ragioni è che
l'Heap Manager deve essere in grado di risalire, a partire dal riferimento
ad un oggetto, alla classe della quale l'oggetto è istanza: pertanto,
durante la creazione di ogni nuovo oggetto, dovrà avere cura di
memorizzare la classe di appartenenza da qualche parte.
Non è rilevante,
ai fini di questa analisi, sapere dettagliatamente come questa informazione venga
mantenuta: è importante solo il fatto che l'Heap Manager saprà
determinare la classe dalla quale il dato oggetto è stato creato.
Un secondo servizio fornito dall'Heap Manager è l'accesso ai
campi degli oggetti. Si osservi, peró, che ogni qual volta
l'interprete ne avesse bisogno ( in seguito, ad esempio, ad un'istruzione
getfield ), sarebbe compito del Class Manager determinare
l'offset al quale il dato campo si trova all'interno dell'oggetto, mentre
l'Heap Manager dovrà al più fornire la classe di appartenenza
dell'oggetto al Class Manager, e l'effettivo accesso alla
locazione indicatagli.
Un ulteriore compito assegnato all'Heap Manager è quello di liberare
la memoria occupata da oggetti non più utilizzabili dal programma
e perció inutili.
Come già accennato, i linguaggi Object-Oriented non prevedono
istruzioni esplicite di deallocazione di memoria e gestiscono tale
problematica automaticamente.
Nel caso della macchina in esame, dal momento che l'Heap Manager è
l'unica componente ad avere accesso diretto all'Heap, sarà ovviamente onere
suo la realizzazione della Garbage Collection per l'Heap.
In poche parole, l'Heap Manager deve riuscire ad identificare, all'interno dell'Heap,
quelle locazioni di memoria per le quali il programma in esecuzione non ha più
alcun riferimento valido.
Ci sono varie tecniche per realizzare ciò ( Mark&Sweep,
Reference Counting, ... ), le quali hanno bisogno di opportune strutture
dati a loro supporto, e talvolta anche di aggiungere in testa ad ogni oggetto
allocato nell'Heap un Header con informazioni ad hoc.
Per completezza osserviamo che un altro problema, annesso alla Garbage Collection,
è quello della Frammentazione della memoria: in seguito alle
continue allocazioni di nuove istanze e alla loro rimozione da parte
del Garbage Collector, l'Heap può degenerare arrivando ad
una situazione in cui spazi pieni e spazi vuoti al suo interno possono
alternarsi fino a portare alla mancanza di sufficiente spazio libero
contiguo per la creazione di nuovi oggetti.
I dettagli relativi all'implementazione di tali tecniche di
Garbage Collection e Deframmentazione esulano dagli scopi
di questa analisi. Ciò che interessa è solo sapere che,
nascoste dentro l'Heap Manager, sono presenti queste sotto componenti che
mantengono l'ordine e la pulizia all'interno dell'Heap.
|