Supporto a run time

Transcript

Supporto a run time
05/01/2014
RUN TIME ENVIRONMENT
MEMORY ORGANIZATION
Compiler must do the storage allocation and
provide access to variables and data
 Memory management




Stack allocation
Heap management
Garbage collection
1
05/01/2014
MEMORY ORGANIZATION

hypothesis





Run time memory is based on
contigued bytes
The smaller addressed space is
a byte (4 bytes = word)
The number of bytes for a date
depend on its type
The memory structure depend
on the target machine
The space (in bytes) required for
the code is calculated at compile
time.
Code
Static
Steak
Free memory
Heap
3
STATIC VS. DYNAMIC ALLOCATION
Static: Compile time, Dynamic: Runtime
allocation
 Many compilers use some combination of
following




Stack storage: for local variables, parameters and so
on
Heap storage: Data that may outlive the call to the
procedure that created it
Stack allocation is a valid allocation for
procedures since procedure calls are nested
2
05/01/2014
STATIC VS. DYNAMIC
Static
Compile time
 Code based

ALLOCATION
Dynamic
Run time
 Code + Data based
 Strategies



Stack allocation
Heap allocation
5
STORIA DELL’ALLOCAZIONE DELLA
MEMORIA
Allocazione statica (Static allocation)
 Una caratteristica del Fortran (fino al Fortran77)
 Implca che le dimenzioni degli arrays sia
conosciuta a compile time
 no funzioni o sottoprogrammi ricorsivi
 Nessuna allocazione dinamica di strutture dati
 Grande Efficienza:
 l’accesso ai dati è di norma diretto
 Sicurezza
 Nessuna possibilita di out of memory a runtime
3
05/01/2014
STORIA DELL’ALLOCAZIONE DELLA
MEMORIA
Stack Allocation
 Introdotta con Algol58
 Il tempo di vita (lifetime) è collegato con l’attivazione
delle procedure
 Implementato attraverso l’utilizzo dei record di
attivazione (stack frame):





Differenti invocazioni istanziano differenti versioni delle
variabili locali; il valore delle variabili locali non persiste fra
successive invocazioni del sottoprogramma
La dimenzione delle strutture dati locali può dipendere da un
parametro
È supportata le ricorsione
La dimenzione del valore ritornato da una funzione deve essere
nota a compile time
Gli oggetti possono essere allocati dinamicamente nello stack ma
sono comunque deallocati quando termina la procedure
STACK ALLOCATION
4
05/01/2014
SKETCH OF A QUICKSORT
PROGRAM
ALLOCAZIONE DELLA MEMORIA
STACK
Alla chiamata di un sottoprogramma una certa
quantità di memoria (per variabili locali etc)
viene impilata nello stack
 Quando il sottoprogramma termina tale memoria
viene rimossa dallo stack
 Cio permette di compilare i sottoprogrammi in
modo che l’indirizzo relativo delle sue variabili
locali sia sempre lo stesso indipendentemente
dalla chiamata

10
5
05/01/2014
ACTIVATION
FOR
QUICKSORT
ALBERO DI ATTIVAZIONE
Dato che le chiamate di procedura sono annidate
nel tempo possiamo utilizzare una
rappresentazione di tale chiamate utilizzando un
albero detto “albero di attivazione”
 Le attivazioni sono riportate sull’albero seguendo
da sx a dx l’ordine in cui sono state chiamate
 Un figlio deve terminare prima che possa iniziare
l’attiviazione alla sua destra
 La sequenza delle chiamate corrisponde ad una
visita in preordine dell’albero di attivazione
 La sequenza dei ritorni corrisponde ad una visita
in postordine dell’albero delle attivazioni

12
6
05/01/2014
ACTIVATION TREE REPRESENTING
CALLS DURING AN EXECUTION OF
QUICKSORT
ACTIVATION
RECORDS
Procedure calls and returns are usaully managed
by a run-time stack called the control stack.
 Each live activation has an activation record
(sometimes called a frame)
 The root of activation tree is at the bottom of the
stack
 The current execution path specifies the content
of the stack with the last activation has record in
the top of the stack.

7
05/01/2014
A GENERAL ACTIVATION RECORD
Temporary values
 Local data
 A saved machine
status
 An “access link”
 A control link
 Space for the return
value of the called
function
 The actual
parameters used by
the calling procedure

DOWNWARD-GROWING STACK OF ACTIVATION
RECORDS
8
05/01/2014
DESIGNING CALLING
SEQUENCES
Values communicated between caller and callee
are generally placed at the beginning of callee’s
activation record
 Fixed-length items: are generally placed at the
middle
 Items whose size may not be known early
enough: are placed at the end of activation record
 We must locate the top-of-stack pointer
judiciously: a common approach is to have it
point to the end of fixed length fields.

DESIGNING CALLING SEQUENCES




The caller evaluates the
actual parameters
The caller stores a return
address and the old value of
top-sp into the callee's
activation record.
The callee saves the register
values and other status
information.
The callee initializes its
local data and begins
execution.
Parameter and
return value
Control link
Stauts
Temporaries an local
data
Parameter and
return value
chiamante
Control link
Stato salvato
Dati temporanei e
locali
18
chiamato
9
05/01/2014
DIMENSION VARIABLE

Two pointers
are required
top_sp e top
top_sp
Parametri attuali e
valore di ritorrno
Control link
Stato salvato
Puntatore ad a
Puntatore ad b
Array a
top
Array b
Parametri attuali e
valore di ritorrno
Control link
Stato salvato
Dati temporanei e
locali
19
CORRESPONDING RETURN
SEQUENCE
The callee places the return value next to the
parameters
 Using information in the machine-status field,
the callee restores top-sp and other registers, and
then branches to the return address that the
caller placed in the status field.
 Although top-sp has been decremented, the caller
knows where the return value is, relative to the
current value of top-sp; the caller therefore may
use that value.

10
05/01/2014
ACCESS TO DYNAMICALLY ALLOCATED
ARRAYS
SEQUENZA DI RITORNO

Il chiamato


Posiziona il valore di ritorno subito dopo i
parametri
Ripristina il registro top.sp e gli altri registri
quindi passa il controllo all’indirizzo di
controllo salvato fra informazioni di stato.
 Recupera il valore dello stack pointer
22
11
05/01/2014
ACCESSO ALLE VARIABILI
NON LOCALI IN
ASSENZA DI PROCEDURE ANNIDATE

Lo scope in tal caso è costituito dalle variabili
locali e dalle variabili globlali


Le variabili globali vengono allocate nella parte di
memoria riservata ai dati statici
Le variabili locali nel record di attivazione del
sottoprogramma dove sono definite
23
ACCESSO
ALLE VARIABILI NON LOCALI IN
PRESENZA DI PROCEDURE ANNIDATE: USO
DELL’ACCESS LINK

La procedura q con livello di annidamento nq richiama la
procedura p con livello di annidamento np
 np > nq, in tal caso p deve essere definita all’interno di q
in tal caso è semplice ad access link di p viene copiato il
valore del record di attivazione di q
 La chiamata è ricorsiva (p=q), in questo caso l’access
link della nuova attivazione è identico alla precedente
 np < nq la procedura q deve essere annidata in r e la
definizione di p deve essere immediatamente annidata
in r. Il recordi di attivazione più recente di r puo essere
localizzato seguento la catena si access link per np – nq
+ 1 passi.
24
12
05/01/2014
ACCESSO ALLO SCOPE TRAMITE
DISPLAY
È un array di puntatori di dimensione pari al
livello di annidamento
 Ciascun puntatore punta al record di attivazione
più in alto nello stack con quel livello di
annidamento

25
ALLOCAZIONE DELLA MEMORIA
Heap Allocation
 Lisp (~1960)
 Gli oggetti sono allocati e deallocati dinamicamente, in qualsiasi
ordine, e il lifetimes degli oggetti non sono correlati con la
invocazione delle funzioni
 Permette strutture dati ricorsive (eg alberi)
 La dimenzione delle strutture dati può variare dinamicamente
 Oggetti dimenzionati dinamicamente possono esser ritornati come
risultato di una funzione
 Permette ai linguaggi di programmazione di supportare “first-class
functions” (che sono implementate per mezzo di closures)
Molti moderni linguaggo forniscono sia stack che heap allocation
26
13
05/01/2014
MEMORY MANAGER

Two basic functions:



Allocation
Deallocation
Properties of memory managers:



Space efficiency
Program efficiency
Low overhead
TYPICAL MEMORY HIERARCHY
CONFIGURATIONS
14
05/01/2014
LOCALITY IN PROGRAMS
The conventional wisdom is that programs spend
90% of their time executing 10% of the code:
 Programs often contain many instructions that
are never executed.
 Only a small fraction of the code that could be
invoked is actually executed in a typical run of
the program.
 The typical program spends most of its time
executing innermost loops and tight recursive
cycles in a program.
ALLOCAZIONE ESPLICITA
SU
HEAP
Esempi sono C, C++, Pascal
dove il programma alloca e
dealloca memoria heap per
gli oggetti
 Garbage = dispersione della
mamoria

Se non ci sono altri puntatori che puntano al
primo alemento della lista quando termina la
funzione gli oggetti diventano irragiungibili
quindi garbage
30
15
05/01/2014
Allocazione esplicita su Heap
Dangling references
free( P->next );
31
Allocazione esplicita su Heap
Dangling references
 which has caused P->next to become a dangling
pointer (and a potential delayed effect run-time
error) as well as creating some garbage
32
16
05/01/2014
PERCHÈ GARBAGE COLLECT?
Quando eseguiamo
list = list->next; // cancella il primo elementoelement
Il programma dovrebbe deallocare gli oggetti condivisi? (questo è complesso
33
ma corretto)
ALLOCAZIONE/DEALLOCAZIONE
ESPLICITA. PROBLEMI?






Quale funzione è responsabile della deallocazione di un
oggetto quando non è più necessario?
Gli oggetti condivisi fra diverse strutture dati rendono
complesso conoscere quando viene rimossa l’ultimo
riferimento
Una soluzione comune è aggiungere un “reference counts”
agli oggetti (ma questa soluzione ha alcuni problemi)
Un alternativa e duplicare (Cloning) gli oggetti in modo da
eliminare il problema della condivisione degli oggetti.
Questa soluzione non è efficiente.
Memory allocation errors are a major source of problems
in C/C++ code (random crashes, memory leaks)
Esistono numerosi tool per la localizzazione di errori di
“memory allocation” (Purify, ObjectCenter, Insure++)
34
17
05/01/2014
GARBAGE COLLECTION
35
THE ESSENCE

Programming is easier if the run-time system
“garbage-collects” --- makes space belonging to
unusable data available for reuse.


Java does it; C does not.
But stack allocation in C gets some of the advantage.
36
18
05/01/2014
DESIDERATA
Speed --- low overhead for garbage collector.
Little program interruption.
1.
2.
Many collectors shut down the program to hunt for
garbage.

Locality --- data that is used together is placed
together on pages, cache-lines.
3.
37
THE MODEL --- (1)

There is a root set of data that is a-priori reachable.


Example: In Java, root set = static class variables plus
variables on run-time stack.
Reachable data : root set plus anything referenced
by something reachable.
38
19
05/01/2014
THE MODEL --- (2)
Things requiring space are “objects.”
 Available space is in a heap --- large area
managed by the run-time system.


Allocator finds space for new objects.


Space for an object is a chunk.
Garbage collector finds unusable objects, returns
their space to the heap, and maybe moves objects
around in the heap.
39
GARBAGE COLLECTION

Garbage collection (GC) - Il processo di recuperare tali record
e renderli disponibili per l'allocazione di nuovi record,
 non viene eseguito dal compilatore, ma a runtime, dai
programmi di supporto collegati al codice compilato (in
quanto, ovviamente, i record presenti in memoria
dipendono dai dati che sono stati inseriti dall'utente).
 Per individuare il garbage, l'approccio ideale sarebbe usare
la definizione dinamica della liveness. Tuttavia, non
essendo questa computabile, ci dobbiamo basare
sull'approssimazione conservativa della raggiungibilità del
record. Il compilatore dovrà garantire che ogni variabile
viva è raggiungibile e, al tempo stesso, minimizzare il
numero di variabili raggiungibili che non sono vive.
40
20
05/01/2014
ESEMPIO DI GARBAGE
class node {
int value;
node next;
}
node p, q;
p = new node();
q = new node();
q = p;
delete p;
41
IL GARBAGE COLLECTOR “PERFETTO”


Nessun impatto visibile sull’esecuzione del
programma
Opera con qualsiasi programma e sulle sue strutture
dati:


Recupera tutte le celle garbage (e solo quelle garbage)
rapidamente


Incrementale, può soddisfare requisiti real-time
Ha un eccellente gestione della localita spaziale dei
riferimenti


Ad esempio gestisce le strutture dati ciclliche
No eccessivo paging, nessun effetto negativo sulla cache
Gestisce l’heap efficentemente

Soddisfa sempre le richieste di allocazione e non provoca
frammentazione della memoria heap.
42
21
05/01/2014
COSTO DEL GC
I primi sistemi Lisp furono noti per i lunghi stop
nel mezzo di sessioni interattive a causa
dell’esecuzione del gc.
 Algoritmi migliori e processori più veloci hanno
reso il gc un problema molto minore.
 GC è ancora da evitare per molte applicazioni
real-time (dove il tempo di risposta richiesto e
inferiore ai millisecondi),
 Per la maggior parte delle applicazioni. Il
problema è:


“Which is more important:software which is free of
memory leaks and memory allocation errors, ... or
software which is a little faster but less reliable and
takes twice as long1 to debug?”
43
A HEAP
Free List
44
...
Object 1
Object 2
Object 3
22
05/01/2014
TAXONOMY
ReferenceCounters
45
Garbage Collectors
TraceBased
REFERENCE COUNTING

The simplest (but imperfect) method is to give each
object a reference count = number of references to this
object.

OK if objects have no internal references.
Initially, object has one reference.
 If reference count becomes 0, object is garbage and its
space becomes available.

46
23
05/01/2014
REFERENCE COUNTING

Una tecnica semplice utilizzata in molti sistemi,


eg, Unix usa tenere traccia di quando un file può essere
cancellato
C++ “smart pointer” (e.g., auto_ptr) usa il e reference counter
Il costo del gc è distribuito sull’intero programma
esecuzione
 Richiede spazio e tempo per memoriazzare e
incrementare (decrementare) il conatore ogni qualvolta
un riferimento ad una cella e aggiunto (eliminato)

47
EXAMPLES
Integer i = new Integer(10);

Integer object is created with RC = 1.
j = k; (j, k are Integer references.)


Object referenced by j has RC--.
Object referenced by k has RC++.
48
24
05/01/2014
TRANSITIVE EFFECTS
If an object reaches RC=0 and is collected, the
references within that object disappear.
 Follow these references and decrement RC in the
objects reached.
 That may result in more objects with RC=0,
leading to recursive collection.

49
REFERENCE COUNTING




Assieme ad ogni record p, viene memorizzato un numero
(reference count) che indica quanti puntatori x.fi a quel
record sono presenti.
Il compilatore emette istruzioni per far sì che ogni volta che
un nuovo x.fi punta a p, il reference count di p viene
incrementato, mentre viene decrementato quello di r a cui
puntava in precedenza.
Se decrementando il reference count di r questo assume il
valore zero, r viene inserito nella freelist.
Se esistono dei record a cui r puntava, il loro refcount deve
essere a sua volta diminuito di uno. Ciò viene fatto non
subito, ma al momento (successivo) in cui r verrà rimosso
dalla freelist, per i seguenti motivi:
viene diviso in più parti il decremento ricorsivo, rendendo
più uida l'esecuzione del programma
2. si risparmia spazio: il codice per il decremento ricorsivo è
unico (nell'allocatore). Il codice per vericare se refcount ha
raggiunto zero, tuttavia, deve comunque essere ripetuto
per ogni decremento.
1.
50
25
05/01/2014
PSEUDO-CODICE PER REFERENCE
COUNTING
// chiamata da New
function allocate():
newcell = freeList;
freeList = freeList.next;
return newcell;
// chiamatta dal programma per creare
// una nuova istanza di un oggetto
function New():
if freeList == null then
report an error;
newcell = allocate();
newcell.rc = 1;
return newcell;
// chiamata da Update
procedure delete(T):
T.rc -= 1;
if T.rc == 0 then
foreach pointer U held
inside object T do
delete(*U);
free(T);
// chiamata dal programma per
// overwrite una variabile
// puntatore R with con un
// altro valore S
procedure Update(var R, S):
if S != null then
S.rc += 1;
delete(*R);
*R = S;
// chiamata da delete
procedure free(N):
N.next = freeList;
freeList = N;
51
rc è il campo reference count dell’oggetto
REFERENCE COUNTING: EXAMPLE
Heap space
root
set
1
2
1
1
1
2
1
1
52
26
05/01/2014
BENEFICI DEL REFERENCE
COUNTING
overhead incrementale
 GC overhead è distribuito lungo tutta la
computazione ==> tempo di risposta omogeneo
nelle situazioni interattive. (Contrasto con
“stop and collect approach”.)
 Applicazioni real-time
 Riuso immediato delle celle libere


se RC == 0, la cella è aggiunta alla put free list
53
BENEFICI DEL REFERENCE COUNTING
Semplicità dell’implementazione
 Può coesistere con la gestione manuale della memoria
heap
 Buona gestione della località spaziale
 il programma accede alle locazioni di memoria che
probabilmente sono sul punto di di essere utilizzare.
(In contrasto con una “marking phase” durante la
quale viene scorsa tutta la memoria)
 la maggioranza degli oggetti hanno una vita breve; il
reference counting recupererà e riutilizzera tali
oggetti rapidamente. (In contrasto con con uno schema
dove gli oggetti morti rimangono inutilizzati per un
lungo periodo vino a quando il prossimo gc a rilevato
un “out of memory”.)

54
27
05/01/2014
REFERENCE COUNTING: PROBLEMI

Space overhead

Time overhead

1 word per il contatore

Ogni volta che un puntatore è aggiornato:
aggiornare due reference counters (decrementare il
vecchio target, incrementare il sorgente).
 L’accesso in memoria è costoso.



Il codice è fragile (se prodotto by hand)
È molto facile dimenticare di incrementare o
decrementare un reference counter (eg quando si
passa un oggetto ad un sottoprogramma)
Dimenticare un incremento ==> strange
bugs,
Dimenticare un decremento ==> memory
leaks.
55
REFERENCE COUNTING: CYCLES
Heap space
Memory leak
root
set
1
1
1
1
1
2
1
1
56
28
05/01/2014
PROBLEMI

Non si può rimuovere memoria garbage con riferimenti ciclici:
se due record non sono raggiungibili, ma puntano l'uno all'altro
vicendevolmente, il loro reference count rimarrà a uno e non
potranno essere rimossi.


Soluzioni
Richiedere esplicitamente che il programmatore elimini tutti i cicli
quando ha finito di usare una struttura
 Combinare Reference Count con qualche Mark&Sweep, per
rimuovere i cicli


La gestione dei reference count è computazionalmente
pesante! Ogni operazione di aggiornamento di un puntatore
implica l'incremento di un reference count, il decremento di
quello della variabile puntata precedentemente e le operazioni
per la verica del raggiungimento di refcount=0. È possibile
attuare qualche ottimizzazione tramite analisi dataflow, ma il
peso è comunque elevato.
57
REFERENCE COUNTING
Strutture dati cicliche
 La soluzione ovvia e combinare reference counting
con gli altri schemi di gc
 Eseguire gli altri schemi di gc quando



La memoria e esaurita
Ad intervalli regolari

Per esempio si possono utilizzare campi di 8 bit per il
counter.
Quando il counter supera il valore massimo, 255, rimane
bloccato
Quando viene eseguito il gc, recupera gli oggetti cil cui
contatore dovrebbe essere zero e resetta i contatori degli
altri oggetti.
Questo permette di utilizzare meno memoria per i
reference counts


58
29
05/01/2014
TAXONOMY
Garbage Collectors
59
ReferenceCounters
TraceBased
Stop-the-World
Mark-andSweep
Short-Pause
Mark-andCompact
Basic
MODELLO ASTRATTO
Gli algoritmi basati sulla traccia calcolano
l’insieme degli oggetti raggiungibili e poi
prendono il complemento di tali oggetti
 Processo di riciclo della memoria




Il programma mutatore viene eseguito ed effettua
richesta di allocazione
Il GC determina la raggiungibilità degli oggetti
mediante algoritmi basati su traccia
Il GC rilascia la memoria degli oggetti non
raggiungibili
60
30
05/01/2014
FOUR STATES
1.
2.
3.
4.
OF
MEMORY CHUNKS
Free = not holding an object; available for
allocation.
Unreached = Holds an object, but has not yet
been reached from the root set.
Unscanned = Reached from the root set, but its
references not yet followed.
Scanned = Reached and references followed.
61
MARKING
1.
2.
3.
Assume all objects in Unreached state.
Start with the root set. Put them in state Unscanned.
while Unscanned objects remain do
examine one of these objects;
make its state be Scanned;
add all referenced objects to Unscanned
if
they have not been there;
end;
62
31
05/01/2014
SWEEPING
Place all objects still in the Unreached state into
the Free state.
 Place all objects in Scanned state into the
Unreached state.


To prepare for the next mark-and-sweep.
63
MARK-SWEEP GARBAGE COLLECTION
Ogni cella ha un “bit di mark”
 Le locazioni di memoria “garbage” rimane non
raggiungibile e inutilizzata fino a quando l’heap non è
piena: quando agisce il GC il programma in esecuzione
viene sospeso
 Fase di Marking



Partendo dai roots, aggiorna il mark bit di tutte le celle
live
Fase di Sweep


Inserisce tutte le celle non marcate nella free list
Reset il mark bit di tutte le celle marcate
64
32
05/01/2014
MARK-SWEEP (AKA MARK-SCAN)
ALGORITHM
Il primo utilizzo sembra essere in Lisp
 La memorizzazione per i nuovi oggetti è ottenuto da
un free-pool
 Nessuna azione extra è eseguita
quando il programma copia o sovrascrive i puntatori
 Quando il pool di libero è
esaurito, il New () invoca il mark-sweep gc per
reinserire la memoria occupata da oggetti
inaccessibili al free-pool e quindi ricomincia

MARK-SWEEP EXAMPLE (1)
Heap space
66
root
set
33
05/01/2014
MARK-SWEEP EXAMPLE (2)
Heap space
67
root
set
MARK-SWEEP EXAMPLE (3)
Heap space
68
root
set
34
05/01/2014
MARK-SWEEP EXAMPLE (4)
Heap space
Free unmarked
cells
69
root
set
Viene
resettato
Il mark bit
Delle celle
marcate
ALGORITMO DI MARK_SWEEP
Fase di marcatura
Poni il reached bit a 1 e aggiungi alla lista Unscanned
ogni oggetto avente un riferimento nel root-set
while (Unscanned != 0){
rimuovi un oggetto o da Unscanned
for (ogni oggetto o’ avente un riferimento in o){
if (il reached-bit di o’ ==0) {
poni il reached-bit di o’ ad 1;
aggiungi o’ alla lista Unscanned
}
}
}

70
35
05/01/2014
ALGORITMO DI MARK_SWEEP
Fase di pulizia
Free = 0;
For (ogni blocco di memoria o nell’heap){
if (il reached-bit di o ==0)
aggiungi o alla lista Free
else poni il reached-bit di o ad 0;
}



La lista Free contiene oggetti disponibili
La lista Unscanned contiene oggetti che sappiamo essere
raggiungibili che non sono stati analizzati per verificare se
fanno riferimento ad altri oggetti
71
COSTO





Il tempo di esecuzione dell'algoritmo DFS è proporzionale
al numero R di nodi segnati (cioè dei record raggiungibili)
ed è proporzionale alla dimensione dello heap H.
L'esecuzione di una garbage collection è quindi c1R + c2H.
Il costo per unità di spazio libero sullo heap, o costo
ammortizzato di raccolta, è dato dal costo di esecuzione
diviso per il numero H − R di parole di memoria libere, cioè
(c1R+c2H)/(H−R) .
Se la memoria è quasi piena (R~ H) il costo è molto elevato.
Se la memoria è quasi vuota (H >> R), il costo è molto
ridotto.
Se al termine del processo di collection R/H è maggiore di
0.5 (o un'altro valore, secondo qualche criterio) il collector
dovrebbe chiedere al sistema operativo di fornire maggiore
spazio per lo heap del programma.
72
36
05/01/2014
TAXONOMY
Garbage Collectors
73
ReferenceCounters
TraceBased
Stop-the-World
Mark-andSweep
Basic
Short-Pause
Mark-andCompact
Baker’s
BAKER’S ALGORITHM --- (1)

Problem: The basic algorithm takes time
proportional to the heap size.


Because you must visit all objects to see if they are
Unreached.
Baker’s algorithm keeps a list of all allocated
chucks of memory, as well as the Free list.
74
37
05/01/2014
BAKER’S ALGORITHM --- (2)
Key change: In the sweep, look only at the list of
allocated chunks.
 Those that are not marked as Scanned are garbage
and are moved to the Free list.
 Those in the Scanned state are put in the
Unreached state.


For the next collection.
75
STATI
Free: zona di memoria disponibile per essere
allocata
 Unreached: blocchi non raggiungibili, tutti i
blocchi inizialmente sono considerati non
raggiungibili e vengono riposti nello stato
unreached dopo il completamento del gc
 I blocchi raggiungibili possono essere



Scanned
UnScanned
76
38
05/01/2014
ALGORITMO DI BAKER
Fase di marcatura
Scanned = 0
UnScanned = insieme degli oggetti raggiungibile
dall’insieme radice
while (Unscanned != 0){
sposta un oggetto o da Unscanned a Scanned
for (ogni oggetto o’ avente un riferimento in o){
if (o’ appartiend a lista UnReached)
sposta o’ da UnReached a Unscanned
}

77
ALGORITMO DI MARK_SWEEP
Fase di pulizia
Free = Free  UnReached;
UnReached = UnScanned

78
39
05/01/2014
OTTIMIZZAZIONI: STACK ESPLICITO
Se si usa un algoritmo DFS standard (ricorsivo),
si potrebbe arrivare ad avere H ricorsioni, e
quindi H frame sulla pila dei record di
attivazione, ossia il garbage collector occuperebbe
più memoria dello HEAP stesso. Ciò è
decisamente da evitare, perciò si preferisce
utilizzare un algoritmo iterativo in cui si gestisce
esplicitamente una struttura a pila su cui salvare
i record marcati.
 In tal modo, si otterrà ugualmente una pila di H
elementi, ma saranno singole word invece che
record di attivazione.

79
OTTIMIZZAZIONI: INVERSIONE DEI
PUNTATORI (POINTER REVERSAL)


Per ridurre ulteriormente lo spazio occupato, si può
osservare che, dopo che il contenuto di un campo x.fi di un
record x è stato salvato sullo stack, è possibile riutilizzare
lo spazio x.fi. In particolare, è possibile utilizzarlo per
salvare il puntatore al record a partire dal quale x era stato
raggiunto.
Secondo questo ragionamento, è quindi possibile utilizzare
lo stesso grafo dei puntatori per salvare anche lo stack,
facendo sì che, mentre si stanno esaminando i campi di un
record (e i campi dei record a cui questi, a loro volta,
puntano), ogni record che si sta esaminando punti al
proprio predecessore (cioè al record da cui è puntato) invece
che al proprio successore (il record a cui punta
normalmente). Ogni volta che tutti i campi di un record
sono stati esaminati, i suoi puntatori vengono ripristinati,
ricostruendo il grafo originale.
80
40
05/01/2014
function DFS(x)
if (x è un puntatore e il record a cui punta non è marcato)
imposta root come predecessore (t)
marca x
while true
if (c'è ancora un campo x.fi (contenente il valore y) da esaminare nel record x)
if (y è un puntatore e il record puntato da y non è marcato)
x.fi t //fai puntare il campo al suo predecessore (pointer reversal)
t  x //x è il predecessore del record che stiamo esaminando
x  y //il record corrente è quello puntato da y marca il record
corrente x
else
dall'inversione
reversal)
y  x //salva in y l'indirizzo del record che stavamo esaminando
x  t //torna ad esaminare il predecessore
if (x=root) tutto il grafo è stato visitato. Fine.
t  x.fi //il nuovo predecessore è quello il cui valore era stato salvato
x.fi  y //ripristino del puntatore originale (fine del pointer
81
OTTIMIZZAZIONE: ARRAY




1.

DI FREELIST
Per ridurre la frammentazione della memoria libera si può utilizzare, invece
di un'unica freelist, un array di freelist, ognuna delle quali corrisponde ad una
certa dimensione dei record ivi contenuti. In tal modo, sarà possibile utilizzare
il blocco di memoria più piccolo di dimensioni sufficienti a contenere la
variabile da allocare.
Se non ci sono blocchi suffientemente piccoli, è possibile usare il più piccolo
disponibile e sprecare una parte dello spazio (se si vuole mantenere la
dimensione dei blocchi), oppure suddividerlo e reimmettere nell'opportuna
freelist la parte di spazio non utilizzata.
La creazione delle diverse freelist è demandata alla fase sweep dell'algoritmo.
L'uso di array di freelist rende anche più veloce anche l'allocazione di nuove
variabili nello heap, perchè l'allocatore non dovrà cercare sequenzialmente in
tutta la freelist un blocco di dimensioni sucienti, ma potrà direttamente
andarlo a richiedere alle freelist di dimensioni opportune.
Frammentazione esterna: sono presenti tanti piccoli record liberi di
dimensione insufficiente per l'allocazione che si vuole eseguire.
Frammentazione interna: non è possibile trovare spazio libero a sucienza
perchè questo è presente, inutilizzato, all'interno di record troppo grandi già
allocati.
82
41
05/01/2014
MARK-SWEEP COSTS AND BENEFITS

Vantaggi


Gestisce le strutture cicliche
Nessun space overhead


1 bit utilizzato per marcarre le celle
Svantaggi




L’esecuzione del programma viene sospesa
Può influenza la gestione della memoria virtuale
Può causare un paging eccessivo se la dimenzione del
working-set size è piccola e l’heap non è tutta nella memoria
fisica
L’heap può essere frammentata
83
TAXONOMY
Garbage Collectors
84
ReferenceCounters
TraceBased
Stop-the-World
Mark-andSweep
Basic
Short-Pause
Mark-andCompact
Baker’s Basic
42
05/01/2014
ISSUE: WHY COMPACT?
Compact = move reachable objects to contiguous
memory.
 Locality --- fewer pages or cache-lines needed to
hold the active data.
 Fragmentation --- available space must be
managed so there is space to store large objects.

85
MARK-AND-COMPACT
Mark reachable objects as before.
Maintain a table (hash?) from reached chunks to
new locations for the objects in those chunks.
1.
2.


Scan chunks from low end of heap.
Maintain pointer free that counts how much space is
used by reached objects so far.
86
43
05/01/2014
MARK-AND-COMPACT --- (2)
Move all reached objects to their new locations,
and also retarget all references in those objects to
the new locations.
3.

4.
Use the table of new locations.
Retarget root references.
87
EXAMPLE: MARK-AND-COMPACT
88
free
44
05/01/2014
EXAMPLE: MARK-AND-COMPACT
89
free
EXAMPLE: MARK-AND-COMPACT
90
free
45
05/01/2014
EXAMPLE: MARK-AND-COMPACT
91
free
EXAMPLE: MARK-AND-COMPACT
92
free
46
05/01/2014
EXAMPLE: MARK-AND-COMPACT
93
free
EXAMPLE: MARK-AND-COMPACT
94
free
47
05/01/2014
EXAMPLE: MARK-AND-COMPACT
95
free
EXAMPLE: MARK-AND-COMPACT
96
free
48
05/01/2014
MARK AND COMPACT

Una volta effettuata la marcatura invece di
procedere alla rimozione è conveniente ricopiare
tutti gli oggetti raggiungibili verso uno dei due
estremi dell’heap
97
ALGORITMO DI MARK_COMPACT
Fase di marcatura
UnScanned insieme degli oggetti raggiungibili
dall’insieme radice
while (Unscanned != 0){
rimuovi un oggetto o da Unscanned
for (ogni oggetto o’ avente un riferimento in o){
if (o’ non è stato ragiunto) {
marca o’ come ragiunto
aggiungi o’ alla lista Unscanned
}
}
}

98
49
05/01/2014
ALGORITMO DI MARK_COMPACT
Calcolo delle nuove locazioni
For (ogni blocco di memoria o nell’heap a partire dal
basso){
if (o è ragiunto) {
for (ofni riferimento o.r in o
new Location(0) = free;
free = free + sizeof(o)
}

99
ALGORITMO DI MARK_COMPACT
Fase di aggiornamento dei riferimenti
For (ogni blocco di memoria o nell’heap a partire dal
basso){
if (o è ragiuunto) {
for (ogni ogni riferimento 0.r in o)
o.r = new Location(o,r) = free;
}
}
for (ogni riferimento r nell’insieme radice)
r = new Location (r);

100
50
05/01/2014
TAXONOMY
Garbage Collectors
101
ReferenceCounters
TraceBased
Stop-the-World
Mark-andSweep
Basic
Short-Pause
Mark-andCompact
Baker’s Basic Cheney’s
A different Cheney, BTW, so no jokes, please.
CHENEY’S COPYING COLLECTOR
A shotgun approach to GC.
 2 heaps: Allocate space in one, copy to second when
first is full, then swap roles.
 Maintain table of new locations.
 As soon as an object is reached, give it the next free
chunk in the second heap.
 As you scan objects, adjust their references to point
to second heap.

102
51
05/01/2014
COPYING COLLECTOR
Lo heap viene diviso in due parti:
 from-space (dove si trovano idati)
 to-space (parte vuota) .
 Attraversando il grafo dei record raggiungibili, si
copiano man mano tali record nel to-space, occupando
senza frammentazione i primi blocchi di memoria
attigui. La copia nel to-space si dice quindi compatta.
 I nodi radice (le variabili dello stack) vengono quindi
fatti puntare ai dati del to-space, rendendo il from-space
non più raggiungibile.
 Alla successiva esecuzione dell'algoritmo, il from-space e
il to-space saranno invertiti.

103
COPYING A LINKED LIST
[Cheney’s algorithm]
pointer
root
A
104
from-space
forwarding address
B
C
D
to-space
A’
B’
C’
D’
Cells in to-space
are packed
52
05/01/2014
FLIPPING SPACES
pointer
105
to-space
forwarding address
from-space
root
A’
B’
C’
D’
COPYING COLLECTOR
Nel from space sono presenti due puntatori: next indica
il punto in cui inizia la parte di memoria libera (e quindi
dove, su richiesta, verranno allocate le prossime aree di
memoria), limit indica il termine dello spazio
disponibile.
 Quando next raggiunge limit, viene eseguita la
collection. Durante il normale funzionamento del
sistema, next può solo crescere: viene ridotto
unicamente dall'esecuzione della collection.
 Quando si comincia l'esecuzione di una collection, next
punta alla base del to-space, e viene incrementato di
size(p) ogni volta che un record p viene copiato.

106
53
05/01/2014
COPYING COLLECTOR

Forwarding È il nome dell'operazione base dell'algoritmo. Si
esegue il forwarding di un puntatore p quando, dato un p che
punta al from-space, lo si modica per puntare agli stessi dati nel
to-space. Funziona in tre sottocasi diversi:
1.
Se p punta ad un record del from-space che è già stato
copiato, allora p.f1 è il forwarding pointer che indica dove si
trova la copia nel to-space. È riconoscibile come tale
dall'indirizzo, che è interno al to-space.
2.
Se p punta al from-space, il contenuto dell'indirizzo puntato
viene copiato nel to-space e p.f1 viene fatto puntare alla
nuova locazione del record.
3.
Se p non è un puntatore oppure se punta al di fuori dal fromspace, il forwarding non fa nulla.
107
COPYING COLLECTOR TRADEOFFS
Vantaggi: basso overhead nell’allocazone
 Il check dell’Out-of-space richiede un confronto fra
indirizzi
 Consente un efficente allocazione di celle di
dimenzioni variabili
 Vantaggi: compattazione
 Elimina la frammentazione, buona localita dei
riferimenti
 Scantaggi: dimenzione della memoria heap disponibile

108
54
05/01/2014
ALGORITMO DI CHENEY
Esegue la copia tramite una visita breadth-rst.
Non necessità di uno stack esterno o
dell'inversione dei puntatori perché introduce,
una copia di puntatori next e un puntatore scan
che indica quali record sono stati scanditi.
 I record compresi tra scan e next, sono stati
copiati nel to-space ma non ancora modicati
tramite forwarding (contengono riferimenti al
fromspace). I record precedenti a scan, invece,
sono già stati modicati dal forwarding
(contengono solo riferimenti al to-space).
 Al termine del processo di collection, scan
raggiunge next.

109
CHENEY SCAN
Root set
A
E
D
C
A
scan
A
F
B
scan
B
A
scan
free
B
C
B
C
free
D
free
Garbage Collection
55
05/01/2014
ALGORITMO DI CHENEY



Località dei riferimenti L'uso di un algoritmo breadth rst
crea problemi con la località dei riferimenti, in quanto
vengono memorizzati in aree adiacenti di memoria i record
che hanno la stessa distanza dalle radici. Avrebbe invece
più senso memorizzare vicini i record che sono connessi da
una catena di puntatori, in quanto è molto più probabile
che si dovrà accedere ad essi in sequenza e, per il
funzionamento delle politiche di paginazione della
memoria, facilmente in questo modo tali record verranno
caricati assieme riducendo il numero di page fault e cache
miss, migliorando sensibilmente le prestazioni.
Una ricerca depth-rst permetterebbe di ottenere maggiore
località, ma richiederebbe l'uso dell'inversione dei
puntatori, risultando quindi piuttosto lenta.
Un buon approccio è quello ibrido, che utilizza breadth-rst
ma che, dopo aver copiato un oggetto, verica tramite depthrst se esiste qualche suo nodo glio da copiargli vicino.
111
LookupNewLocation(o){
/*cerca la nuova posizione di un oggetto se è stato
spostato altrimenti assegna all’oggetto lo stato
unscanned*/
if (NerLocation(o) == null) {
NewLocation(o) = free
free = free + sizeof(o)
copia o in NewLocation(o);
}
Return NewLocation(o);
}
112
56
05/01/2014
CopyingCollector(){
for (ogni oggetto o nel semispazio From)
NewLocation(o) = null
unscanned = free = indirizzo base semispazio To
for (ogni riferimento r nel root set)
sostituisci r con LookupNewLocation(r)
while (unscanned == free) {
o = oggetto alla locazione unscanned
for (ogni riferimento o.r in o)
o.r= LookupNewLocation(o,r);
unscanned = unscanned + sizeof(o)
}}
113
CONFRONTO FRA MARK-SWEEP E
COPYING COLLECTION
Detti



M = dimenzione dell’heap
R = percentuale di oggetti vivi
Tutti gli oggetti vivi devono essere copiati da un Copying
Collector, cosi il tempo e proporzionale a R:
tcc = aR
Copyng collector visita tutti gli oggetti vivi e sweeps tutti
gli elementi dell’heap, cosi il suo tmpo ha due componenti
:
tms = bR +cM
Dove a, b, c sono costanti
114
57
05/01/2014
CONFRONTO
Spazio recuperato dal gc
mcc = M/2 – R
mms = M – R
 Efficienza e = byte recuperati al secondo
ecc = 1/2ar – 1/a
ems = (1-r)/(br + c)
Dove r = R/M

115
CONFRONTO
116
58
05/01/2014
GENERATIONAL GARBAGE COLLECTION

Osservazione: la maggior parte delle celle, che muoino,
muoiono giovani



Scope annidati sono entrato ed uscito più di frequente, gli oggetti
temporanei in uno scope ambito nidificato nascono
e muoiono ravvicinati nel tempo
Espressioni interne in Scheme sono più
giovani di espressioni esterne, in tal modo diventano “garbace
prima
Dividere l'heap in generazioni, e GC le cellule più
giovani più frequentemente



Non ci sono tutte le celle durante il ciclo di GC
Periodicamente raccoglie li "vecchie generazioni”
Ammortizzare il costo di generazione in generazione
117
TAXONOMY
Garbage Collectors
118
ReferenceCounters
TraceBased
Stop-the-World
Mark-andSweep
Basic
Mark-andCompact
Short-Pause
Incremental
Partial
Baker’s Basic Cheney’s
59
05/01/2014
SHORT-PAUSE GARBAGE-COLLECTION
Incremental --- run garbage collection in
parallel with mutation (operation of the
program).
Partial --- stop the mutation, but only briefly,
to garbage collect a part of the heap.
1.
2.
119
PROBLEM WITH INCREMENTAL GC
OK to mark garbage as reachable.
 Not OK to GC a reachable object.
 If a reference r within a Scanned object is mutated
to point to an Unreached object, the latter may be
garbage-collected anyway.


Subtle point: How do you point to an Unreached object?
120
60
05/01/2014
ONE SOLUTION: WRITE BARRIERS
Intercept every write of a reference in a scanned
object.
 Place the new object referred to on the
Unscanned list.
 A trick: protect all pages containing Scanned
objects.


A hardware interrupt will invoke the fixup.
121
ALGORITMI DI GC INCREMENTALI

Per ridurre il tempo di interruzione dell'esecuzione di un
programma durante il GC, è possibile usare algoritmi
incrementali, cioè che non conducono l'intero processo di
collection in un unico passaggio, ma lo eseguono un pezzo
alla volta inframezzandosi alla normale esecuzione del
programma.



Collector:l'algoritmo di collection
Mutator: il programma in esecuzione (in quanto è in grado di
modicare i dati su cui si sta lavorando).
Generalmente gli algoritmi incrementali si basano su un
processo di segnatura a tre colori per stabilire
l'avanzamento dell'algoritmo. I record possono essere:



Bianchi oggetti non ancora visitati dall'algoritmo di ricerca
depth-rst o breadth-rst.
Grigi gli oggetti sono già stati visitati, ma i loro figli no (è come
se si trovassero sulla pila, o tra scan e next)
Neri sia gli oggetti sia tutti i loro gli sono già stati visitati e
marcati (è come se fossero già stati tolti dalla pila, o se fossero
prima di scan).
122
61
05/01/2014
INCREMENTAL COLLECTION



A partire dalle radici, si visitano tutti gli oggetti,
rendendoli prima grigi, visitando i loro figli e infine
rendendoli neri. Quando non sono più presenti oggetti grigi,
tutto ciò che è rimasto bianco è garbage.
Due invarianti sono comuni a tutti gli algoritmi che si
basano su questo principio:
 Gli oggetti neri non possono puntare a oggetti bianchi
 Ogni oggetto grigio è sulla struttura dati (pila o coda)
del collector.
Il mutator, durante il suo lavoro, deve fare attenzione a
non rompere tali invarianti, introducendo opportune
politiche di coloratura: ad esempio, nell'algoritmo di
Dijkstra, Lamport e altri, quanto il mutator salva un
puntatore bianco a dentro ad unoggetto nero b, deve
colorare a di grigio.
123
LAYOUT DEI DATI


Il collector deve essere in grado di operare su qualunque
tipo di dato, anche complesso. Deve quindi essere in grado
di determinare
1. la dimensione occupata dai dati di ogni record, il
numero di campi da cui è formato e se questi campi
contengono o meno un puntatore
2. La prima word di un oggetto generalmente viene fatta
puntare ad un record di descrizione del tipo (o della
classe) che contiene l'indicazione della dimensione e la
posizione dei campi puntatore. Tale record deve essere
stato creato dal compilatore grazie alle informazioni
ricavate dall'analisi semantica.
Il compilatore deve anche permettere al collector di
identicare se qualunque temporary (registro o area di
memoria) contiene un puntatore. Ciò viene fatto
compilando un'apposita mappa dei puntatori (pointer map)
ogni volta che potrebbe essere necessario eseguire una
collection, cioè ad ogni operazione alloc.
124
62
05/01/2014
TAXONOMY
Garbage Collectors
125
ReferenceCounters
TraceBased
Stop-the-World
Mark-andSweep
Basic
Mark-andCompact
Baker’s Basic Cheney’s
Short-Pause
Incremental
Partial
Generational
THE OBJECT LIFE-CYCLE

“Most objects die young.”


But those that survive one GC are likely to survive
many.
Tailor GC to spend more time on regions of the
heap where objects have just been created.

Gives a better ratio of reclaimed space per unit time.
126
63
05/01/2014
PARTIAL GARBAGE COLLECTION

We collect one part(ition) of the heap.
The target set.


We maintain for each partition a remembered set
of those objects outside the partition (the stable
set) that refer to objects in the target set.
Write barriers can be used to maintain the
remembered set.

127
COLLECTING

PARTITION
To collect a part of the heap:
1.
2.

A
Add the remembered set for that partition to the
root set.
Do a reachability analysis as before.
Note the resulting Scanned set may include
garbage.
128
64
05/01/2014
EXAMPLE: “REACHABLE” GARBAGE
In the remembered set
129
The target
partition
Not reached from
the root set
Stable set
GENERATIONAL GARBAGE COLLECTION

Divide the heap into partitions P0, P1,…

Each partition holds older objects than the one before
it.
Create new objects in P0, until it fills up.
 Garbage collect P0 only, and move the reachable
objects to P1.

130
65
05/01/2014
GENERATIONAL GC --- (2)
When P1 fills, garbage collect P0 and P1, and put
the reachable objects in P2.
 In general: When Pi fills, collect P0, P1,…,Pi
and put the reachable objects in P(i +1).

131
EXAMPLE WITH IMMEDIATE “AGING” (1)
A
B
D
132
C
root
set
Young
E
F
Old
G
66
05/01/2014
EXAMPLE WITH IMMEDIATE “AGING” (2)
D
133
C
root
set
Young
E
A
G
F
Old
B
GENERATIONS WITH SEMI-SPACES
Youngest
.
.
.
From-space
134
root
set
To-space
Middle
generation(s)
Oldest
From-space
To-space
67
05/01/2014
Riduce sia il tempo sia lo spazio usati dal metodo
copying collection.
 Si basa sull'osservazione che molti oggetti sono
destinati a morire presto, ma se un oggetto è
sopravvissuto già ad alcune collection, è probabile
che sopravviva a lungo.
 L’ heap è diviso in generazioni: G0 contiene gli
oggetti più giovani. Tutti gli oggetti di G1 sono
più vecchi di quelli di G0; gli oggetti in G2 sono
più vecchi di quelli di G1 e così via.
 Ogni area dovrebbe essere esponenzialmente più
grande della precedente (es: G0 = 0.5MB,G1 =
2MB,G2 = 8MB).
 Un oggetto che è sopravvissuto a due o tre
collection viene promosso a quella successiva.

135



Al momento di eseguire una collection (si può usare sia il
metodo mark&sweep sia copying collection) la si esegue
prima su G0 e poi, se necessario, sulle generazioni via via
successive.
Per trovare gli elementi di G0, non basta guardare le
variabili nello stack: potrebbero esistere anche riferimenti
all'interno di oggetti vecchi che puntano a oggetti più
nuovi. Questa condizione (per fortuna rara, perchè richiede
l'aggiornamento di un campo di un oggetto vecchio)
renderebbe l'analisi del solo G0 più lenta che non
l'attraversamento di tutto il grafo a partire dalle radici.
Per ovviare al problema facciamo si che il programma
compilato ricordi dove ci sono puntatori da oggetti vecchi ad
oggetti nuovi, in modo da poterli trovare immediatamente.
Esistono diversi metodi per fare ciò.
136
68
05/01/2014
1.
2.
3.
4.

Remembered list: viene generata una lista di oggetti di cui un campo
è stato aggiornato. Al momento del GC si cercano all'interno della lista
gli oggetti che puntino dentro G0
Remembered set La remembered list potrebbe contenere duplicati di
uno stesso oggetto al suo interno. Per evitare il problema, si codica
all'interno dello stesso oggetto un bit per indicare l'appartenenza o
meno al remembered set.
Card marking La memoria è divisa in schede di dimensione 2k. Un
oggetto può occupare una o più schede, o parte di una scheda. Ogni
volta che un indirizzo b viene modicato, la scheda contenente
quell'indirizzo viene marcata (tramite un bit in un apposito array)
Page marking Simile al precedente, ma invece di introdurre una
gestione manuale delle schede, si usa la paginazione della memoria.
Quando un indirizzo viene modicato, un dirty bit viene impostato per
quella pagina.
In ogni caso, all'inizio della garbage collection, il set di oggetti ricordati
indica quali oggetti potrebbero contenere puntatori a G0. Questi oggetti
assieme alle variabili dello stack fungono da root variables per
l'algoritmo di ricerca scelto.
137
TAXONOMY
Garbage Collectors
138
ReferenceCounters
TraceBased
Stop-the-World
Mark-andSweep
Basic
Mark-andCompact
Baker’s Basic Cheney’s
Short-Pause
Incremental
Partial
Generational Train
69
05/01/2014
THE TRAIN ALGORITHM
Problem with generational GC:

1.
2.
Occasional total collection (last partition).
Long-lived objects move many times.
Train algorithm useful for long-lived objects.

u
Replaces the higher-numbered partitions in
generational GC.
139
PARTITIONS = “CARS”
Car 11
Car 12
Train 2
Car 21
Car 22
Car n1
Car n2
140
Train 1
Car 13
...
Car 2k
.
.
.
Train n
70
05/01/2014
ORGANIZATION OF HEAP

There can be any number of trains, and each
train can have any number of cars.


You need to decide on a policy that gives a reasonable
number of each.
New objects can be placed in last car of last train,
or start a new car or even a new train.
141
GARBAGE-COLLECTION STEPS
Collect the first car of the first train.
Collect the entire first train if there are no
references from the root set or other trains.
1.
2.

Important: this is how we find and eliminate large,
cyclic garbage structures.
142
71
05/01/2014
REMEMBERED SETS
Each car has a remembered set of references
from later trains and later cars of the same train.
 Important: since we only collect first cars and
trains, we never need to worry about “forward”
references (to later trains or later cars of the
same train).

143
COLLECTING
FIRST TRAIN
THE
FIRST CAR OF THE
Do a partial collection as before, using every other
car/train as the stable set.
 Move all Reachable objects of the first car
somewhere else.
 Get rid of the car.

144
72
05/01/2014
MOVING REACHABLE OBJECTS

If object o has a reference from another train,
pick one such train and move o to that train.


Same car as reference, if possible, else make new car.
If references only from root set or first train,
move o to another car of first train, or create new
car.
145
PANIC MODE
The problem: it is possible that when collecting
the first car, nothing is garbage.
 We then have to create a new car of the first
train that is essentially the same as the old first
car.

146
73
05/01/2014
PANIC MODE --- (2)

If that happens, we go into panic mode, which
requires that:
1.
2.
If a reference to any object in the first train is
rewritten, we make the new reference a “dummy”
member of the root set.
During GC, if we encounter a reference from the “root
set,” we move the referenced object to another train.
147
PANIC MODE --- (3)
Subtle point: If references to the first train never
mutate, eventually all reachable objects will be
sucked out of the first train, leaving cyclic
garbage.
 But perversely, the last reference to a first-train
object could move around so it is never to the first
car.

148
74