Gestione della Memoria - LACAM - Università degli Studi di Bari
Download
Report
Transcript Gestione della Memoria - LACAM - Università degli Studi di Bari
Gestione della Memoria
Nicola Fanizzi
Linguaggi di
Dipartimento di Informatica Programmazione [010194]
Università degli Studi di Bari 27 apr, 2016
Sommario
1
Tecniche di gestione
Progetto della gestione della memoria
Tipologie
2
Gestione statica
3
Gestione dinamica
Blocchi
Record di attivazione
Gestione della pila
Gestione dinamica con heap
4
Implementazione delle regole di scope
Scope statico
Puntatore di catena statica
Display
Scope dinamico
Lista di associazioni
CRT
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
2 / 54
Agenda
1
Tecniche di gestione
Progetto della gestione
della memoria
Tipologie
LdP.ITPS/[email protected]
2
Gestione statica
3
Gestione dinamica
4
Implementazione delle
regole di scope
Gestione della Memoria
27 apr, 2016
3 / 54
Progetto della gestione della memoria
Programmi e dati
Allocazione
Durata
Strutture dati ausiliarie per la gestione
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
4 / 54
Tipologie
Macchina astratta di basso livello
Gestione statica: dati e programmi in memoria prima
dell’esecuzione e fino alla fine
Macchina astratta di alto livello
Gestione dinamica: allocazione e deallocazione decisa
durante l’esecuzione
Ricorsione: il compilatore non può stabilire un numero
massimo di sottoprogrammi attivi
Uso di una Pila (politica LIFO)
Allocazione dinamica esplicita
Uso dell’Heap
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
5 / 54
Agenda
3
1
Tecniche di gestione
4
2
Gestione dinamica
Implementazione delle
regole di scope
Gestione statica
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
6 / 54
Gestione statica
Gestione ad opera del compilatore
Tutti gli oggetti in una zona fissata
Variabili globali
Istruzioni del codice oggetto
Costanti
Tabelle interne prodotte dal compilatore:
Gestione nomi
Controllo sui tipi
Garbage collection
Linguaggio senza ricorsione
Zona di memoria fissata per ogni sottoprogramma
Variabili locali
Parametri
Indirizzo di ritorno
Info di bookkepping
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
7 / 54
Gestione statica [. . . cont.]
sottoprogramma p2
sottoprogramma p1
Informazioni
di sistema
Indirizzo
di ritorno
Parametri
sottoprogramma pn
Informazioni
di sistema
Informazioni
di sistema
Indirizzo
di ritorno
Parametri
Indirizzo
di ritorno
Parametri
Variabili Locali
Variabili Locali
Variabili Locali
Risultati
Intermedi
LdP.ITPS/[email protected]
Risultati
Intermedi
...
Gestione della Memoria
Risultati
Intermedi
27 apr, 2016
8 / 54
Gestione statica – Problema
Osservazioni
chiamate successive dello stesso sottoprogramma
condividono la stessa area di memoria
ricorsione:
int fib (int n) {
if (n == 0) return 1;
3
else if (n == 1) return 1;
4
else return fib(n-1) + fib(n-2);
5}
1
2
il numero di chiamate ricorsive dipende dall’argomento n:
servono più copie dell’area di memoria dedicata ad ogni
sottoprogramma (una per chiamata)
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
9 / 54
Agenda
1
Tecniche di gestione
2
Gestione statica
3
Gestione dinamica
Blocchi
Record di attivazione
Gestione della pila
Gestione dinamica con
heap
4
LdP.ITPS/[email protected]
Implementazione delle
regole di scope
Gestione della Memoria
27 apr, 2016
10 / 54
Gestione dinamica
Rinviene dall’uso della strutturazione a blocchi dei
programmi
In-line
Corpi di sottoprogrammi
Apertura e chiusura
politica LIFO
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
11 / 54
Blocchi
1
A: {
int a = 1;
int b = 0;
B: {
int c = 3;
int b = 3;
}
b = a+1;
2
3
4
5
6
7
8
9
}
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
12 / 54
Blocchi [. . . cont.]
1
b
a
2
0
1
LdP.ITPS/[email protected]
A
3
b
a
0
1
A
b
c
3
3
B
Gestione della Memoria
b
a
2
1
27 apr, 2016
A
13 / 54
Record di attivazione
Spazio di memoria allocato su pila
(noto anche come frame)
per i blocchi in-line
per il corpo di sottoprogramma
Associato ad ogni attivazione (dinamicamente)
e non alla dichiarazione (staticamente)
Pila di run-time (o di sistema)
Utilizzato anche per linguaggi senza ricorsione
per ottimizzare l’occupazione della memoria
rispetto ad una politica interamente di tipo statico
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
14 / 54
Record di attivazione [. . . cont.]
Un RdA in-line contiene:
Risultati intermedi
punta al precedente RdA
sulla pila
necessario date le diverse
dim. dei RdA
calcoli complessi
semplificati dal
compilatore
RdA Blocco Inline
Variabili locali
dichiarate nel blocco
dimensioni note a
compile-time
Eccezione: dim. array
dinamici gestite con
(parte fissa,
parte variabile)
Puntatore catena dinamica
ovvero link dinamico o di
controllo
LdP.ITPS/[email protected]
Gestione della Memoria
Puntatore di catena
statica / dinamica
Variabili
locali
Variabili
temporanee
27 apr, 2016
15 / 54
Record di attivazione [. . . cont.]
Nel RdA di sottoprogramma:
Risultati intermedi
Variabili locali
Punt. di catena dinamica
Punt. di catena statica
RdA di Sottoprogramma
Puntatore di catena dinamica
Puntatore di catena statica
Indirizzo di ritorno
Indirizzo dei risultati
se si adotta tale scope
Indirizzo di ritorno
Parametri
prima istruzione da
eseguire dopo l’uscita
Indirizzo del risultato
Variabili locali
nel RdA del CHIAMANTE
per funzioni
Parametri
Risultati intermedi
Valori dei parametri
effettivi usati dal
sottoprogramma
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
16 / 54
Record di attivazione [. . . cont.]
Osservazioni
La disposizione dei campi effettiva dipende dalle
implementazioni
Si usano offset per individuare i vari campi
di norma,
non compaiono identificatori di variabili (locali e non):
il compilatore calcola gli offset
Ottimizzazione
Es.: salvataggio di informazioni nei registri anziché nel RdA
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
17 / 54
Gestione della pila
Puntatore di RdA (o frame pointer):
si riferisce all’ambiente corrente
Stack pointer dell’inizio della memoria libera
Operazioni su RdA
Inserimento
entrata in un blocco
chiamata di sottoprogramma
eliminazione
uscita dal blocco
uscita da sottoprogramma
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
18 / 54
Gestione della pila [. . . cont.]
fondo della pila
RdA
RdA
..
puntatore RdA
RdA
cima della pila
zona libera
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
19 / 54
Gestione della pila [. . . cont.]
Codice aggiunto dal compilatore
nel CHIAMANTE (o blocco esterno):
sequenza di chiamata
eseguita, in parte, prima della chiamata (entrata)
eseguita, in parte, al ritorno dalla chiamata (uscita)
nel CHIAMATO (o blocco interno):
prologo
eseguito subito dopo la chiamata (entrata)
epilogo
eseguito subito prima del ritorno dalla chiamata (uscita)
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
20 / 54
Azioni
chiamata / entrata (seq. di chiamata + prologo):
modifica del PC
allocazione spazio su pila
modifica puntatore RdA
passaggio parametri
salvataggio registri
esecuzione codice inizializzazione
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
21 / 54
Azioni [. . . cont.]
ritorno / uscita (ritorno controllo di chiamata + epilogo):
ripristino del PC
restituzione dei valori (funzioni)
ripristino registri (+modifica puntatore RdA)
esecuzione codice finalizzazione
deallocazione spazio su pila
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
22 / 54
Gestione dinamica con heap
Per linguaggi con allocazione esplicita della memoria
C, C++, PASCAL, ...
non si può seguire una politica LIFO
Si utilizza una zona di memoria diversa dallo stack:
HEAP
gestito con blocchi
di dim. fissa
di dim. variabile
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
23 / 54
Gestione dinamica con heap [. . . cont.]
int *p, *q; /* p,q puntatori a var. intere; val. NULL */
p = malloc (sizeof (int)); /* alloca var. puntata da p */
3 q = malloc (sizeof (int)); /* alloca var. puntata da q */
4 *p = 0; /* dereferenzia ed assegna */
5 *q = 1; /* dereferenzia ed assegna */
6 free(p); /* dealloca la var. puntata */
7 free(q); /* dealloca la var. puntata */
1
2
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
24 / 54
Blocchi di dim. fissa
Heap suddiviso in blocchi di dimensioni fisse e limitate
collegati in una struttura di lista detta lista libera
allocazione
il primo elemento della lista libera viene rimosso
il puntatore a tale elemento viene restituito
si aggiorna il puntatore al primo elemento della lista
libera all’elemento successivo
deallocazione
il blocco liberato viene collegato in testa alla lista libera
si aggiorna il puntatore all’elemento successivo a quello
aggiunto
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
25 / 54
Blocchi di dim. fissa [. . . cont.]
inizio lista
inizio lista
..
.
LdP.ITPS/[email protected]
..
.
Gestione della Memoria
27 apr, 2016
26 / 54
Blocchi di dim. variabile
Dim. fissa: inadeguata per strutture grandi
Esempio grande vettore di dim. variabili
Blocchi di dim. variabile: gestione tesa ad ottimizzare
(con opportuni compromessi)
1
l’occupazione della memoria
frammentazione
interna porzione di blocco allocato inutilizzato
esterna memoria libera sufficiente nel complesso, ma
non in un unico blocco
necessità di ricompattamento
2
l’efficienza dell’esecuzione
basso numero di operazioni aggiuntive richieste (overhead)
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
27 / 54
Blocchi di dim. variabile [. . . cont.]
LL
fabbisogno
x
x+y
y
..
.
frammentazione esterna
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
28 / 54
Unica lista libera
Inizialmente un blocco pari a tutta la mem. disponibile (heap)
richiesta di allocazione soddisfatta usando le prime n parole
avanza il puntatore LL
analogamente per le successive richieste
i blocchi deallocati (non contigui) formano una catena
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
29 / 54
Unica lista libera [. . . cont.]
Quando non c’è più spazio sull’heap:
1
utilizzo diretto della lista libera
si mantiene una lista di blocchi liberi di dim. variabile
allocazione: si cerca nella lista un blocco di dim. k ≥ n utile al
fabbisogno
criterio first-fit
criterio best fit
(migliore efficienza)
(migliore occupazione)
la porzione di blocco k − n non usata resta nella lista libera
deallocazione: si ricompatta il blocco
eventualmente assieme ai blocchi liberi adiacenti
2
compattazione della mem. libera
in caso di esaurimento dello spazio direttamente allocabile:
spostamento dei blocchi attivi (solo se rilocabili)
compattamento dei blocchi liberi in un’estremità della
memoria
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
30 / 54
Multiple liste libere
Molteplici liste ognuna contenente di blocchi di diverse
grandezze
per un fabbisogno pari ad n
allocazione:
selezione della lista con blocchi di dim. k con k ≥ n
allocazione usando tale lista come nel caso di singola lista
libera
deallocazione: idem
Osservazione
frammentazione interna se le dim. sono statiche
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
31 / 54
Multiple liste libere [. . . cont.]
buddy system: dim. dei blocchi potenze di 2
allocazione: sia k tale che blocco di dim. 2k > n
se libero viene allocato
altrimenti si considera un blocco della lista 2k+1
e lo si divide in due parti
1
2
una viene allocata
l’altra diventa un blocco libero tra i blocchi 2k
deallocazione:
ricerca del compagno (buddy)
se libero fusione in un blocco di dim. 2k+1
heap di Fibonacci: come il precedente
la successione di Fibonacci cresce più lentamente
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
32 / 54
Agenda
3
1
Tecniche di gestione
4
2
Gestione dinamica
Gestione statica
LdP.ITPS/[email protected]
Implementazione delle
regole di scope
Scope statico
Scope dinamico
Gestione della Memoria
27 apr, 2016
33 / 54
Implementazione delle regole di scope
Riferimenti nel RdA: nomi locali
Nomi non locali?
ricerca nei RdA attivi sulla pila
ordine dipende dal tipo di scope adottato:
statico | dinamico
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
34 / 54
Scope statico
Ordine di ricerca di riferimenti non-locali
diverso da quello dei blocchi sulla pila
A:{ int y=0;
B:{ int x = 0;
3
void P (int n) {
4
x = n+1;
5
y = n+2;
6
}
7
C:{ int x = 1;
8
P(2);
9
write(x);
10
}
11
}
12
write(y);
13 }
1
2
dopo la chiamata di P, sulla pila:
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
35 / 54
Scope statico [. . . cont.]
y
int
...
0
A
P
A
p. RdA attivo
LdP.ITPS/[email protected]
x
int
P
fun
...
x
int
...
1
C
n
int
...
1
P
0
B
B
C
codice
Gestione della Memoria
27 apr, 2016
36 / 54
Scope statico [. . . cont.]
RdA di un blocco B collegato mediante puntatore di catena
statica al blocco immediatamente esterno che lo contiene nel
sorgente
B blocco di sottoprogramma:
il blocco esterno a B ne contiene la dichiarazione
B attivo:
anche i blocchi esterni che lo contengono devono essere attivi
(RdA sulla pila)
vengono mantenute quindi 2 catene (cfr. fig. seguente)
gestione tramite codice:
sequenza di chiamata, prologo ed epilogo
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
37 / 54
Scope statico [. . . cont.]
Esempio
catena statica (e dinamica) per la struttura a destra
A
B
B
C
D
E
A
D
C
C
E
.
.
.
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
38 / 54
Calcolo puntatore di catena statica
In genere, all’ingresso in un blocco:
il CHIAMANTE calcola del punt. di catena statica del CHIAMATO
e glielo passa
2 casi:
1
CHIAMATO
all’esterno del CHIAMANTE
perché sia visibile, il CHIAMATO deve trovarsi in un blocco
esterno che includa anche il CHIAMANTE
(quindi il RdA di questo blocco esterno è già sulla pila)
numero di livelli di distanza determinabile dal compilatore:
k = livello(CHIAMATO) − livello(CHIAMANTE)
si seguono k livelli di catena statica
2
CHIAMATO
all’interno del CHIAMANTE
per la visibilità, il CHIAMATO è dichiarato nel blocco della
chiamata
per il CHIAMANTE, basta risalire al blocco esterno
k=1
il CHIAMATO (prologo) memorizza il puntatore di catena
statica ricevuto nel suo RdA
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
39 / 54
Calcolo puntatore di catena statica [. . . cont.]
il compilatore tiene traccia del liv. di annidamento delle
chiamate usando la tavola dei simboli:
nome + numero di scope
nell’es. precedente, per risolvere y in P calcola distanza 2 da A
dov’è la sua dichiarazione
tuttavia non può risolvere tutti i riferimenti;
alcuni sono legati al numero di RdA presenti sulla pila a
run-time
Osservazione svantaggio: per una distanza pari a k,
si devono scorrere k livelli di catena statica
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
40 / 54
Scope statico / Display
Obiettivo: ridurre ad un numero costante gli accessi
display: vettore di dim. pari a numero di livelli di annidamento
display[k]: puntatore al RdA di livello k attivo
Per ogni riferimento ad un nome non locale:
dichiarato in blocco esterno a livello k
il puntatore al RdA è nel display nella posizione k
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
41 / 54
Scope statico / Display [. . . cont.]
Gestione semplice ma più costosa:
all’entrata in nuovo ambiente di livello k,
si salva (nel CHIAMATO) il valore precedente di display[k],
se presente
condivisione del display in toto o in parte col CHIAMANTE
si aggiorna display[k] con il puntatore del RdA del CHIAMATO
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
42 / 54
Scope statico / Display [. . . cont.]
Siano n liv. del CHIAMANTE e m liv. del CHIAMATO
1
CHIAMATO
all’esterno del CHIAMANTE
m<n
condivisione della str. statica fino al liv. m − 1
si aggiorna display[m] per puntare al RdA del CHIAMATO,
salvando il contenuto precedente
il display è attivo fino alla pos. m;
all’uscita verrà ripristinato
2
CHIAMATO
all’interno del CHIAMANTE
m>n
condivisione del display fino al livello n
si incrementa il liv. di profondità del display e
inserisci il puntatore al RdA del CHIAMATO in display[n + 1]
se si era già arrivati a liv. n + 1,
si salva il vecchio contenuto presente
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
43 / 54
Scope statico / Display [. . . cont.]
vantaggio: semplicità
ambienti non locali considerati secondo l’ordine di chiamata
svantaggi:
necessità di memorizzare esplicitamente i nomi per la ricerca
può essere inefficiente far tutto il lavoro a run-time
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
44 / 54
Scope statico / Display [. . . cont.]
chiamate nell’ordine
A B C D E C
a sinistra della pila puntatori
relativi ai vecchi valori nei
display nella pos. del CHIAMATO
linea tratteggiata p. non attivo
A:
[
B:
C:
[ ],
[
D:
E:
]
[ ],
[ ]
]
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
45 / 54
Scope dinamico / Lista di associazioni
memorizzazione associazioni nome/oggetto
nel RdA, oppure
in una lista di associazioni (A-list) gestita come una pila
entrata/uscita in/da un nuovo ambiente:
nuove associazioni vengono inserite/eliminate nella/dalla lista
info:
locazione
tipo
altre info necessarie a controlli semantici
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
46 / 54
Scope dinamico / Lista di associazioni [. . . cont.]
...
A
x
y
x
y
...
x
B v
...
B
x
v
A
...
...
C
w
D
C
w
x
w
x
...
...
D
p. RdA attivo
w
...
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
47 / 54
Scope dinamico / Lista di associazioni [. . . cont.]
/
x
y
tipo, locazione, . . .
x
y
”
x
”
v
”
x
B v
A
w
p. A-List
LdP.ITPS/[email protected]
w
”
x
”
w
”
Gestione della Memoria
D
C
w
x
27 apr, 2016
48 / 54
Scope dinamico / CRT
Si ovvia agli svantaggi di altri metodi a scapito dell’efficienza
tutti i blocchi in un’unica tabella: CRT
Central Referencing environment Table
tutti i nomi presenti;
per ogni nome:
flag (associazione attiva sì/no)
puntatore alle informazioni associate (locazione, tipo, . . . )
se tutti i nomi sono noti a compile-time
ricerca in tempo costante (ind.tabella + offset)
altrimenti: ricerca hash
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
49 / 54
Scope dinamico / CRT [. . . cont.]
Ingresso da A in B:
modifica della CRT per un nuovo ambiente locale di A
non necessariamente in entry contigue nella tabella
salvataggio associazioni disattivate (in una pila) per successivo
ripristino all’uscita da B
Pila
esplicita
top: associazione attiva
altre: associazioni disattivate
nascosta (separata dalla CRT)
(nome, flag, rif. ad oggetto)
non è richiesta ricerca
accesso (diretto o hash) alla tabella, che contiene l’info
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
50 / 54
Scope dinamico / CRT [. . . cont.]
in C
in B
x
info
y
info
/
v
info
/
w
info
in A
info
info
in D
info
/
/
in C
chiamate di A, B, C, D
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
51 / 54
Scope dinamico / CRT [. . . cont.]
A
ABC
AB
ABCD
x
1
α1
x
1
β1
x
1
γ1
x
1
γ1
y
1
α2
y
1
α2
y
1
α2
y
1
α2
v
0
−
v
1
β2
v
0
β2
v
0
β2
w
0
−
w
0
−
w
1
γ2
w
1
δ1
stack nascosto
LdP.ITPS/[email protected]
x
α1
x
α1
x
α1
x
β1
x
β1
w
γ1
Gestione della Memoria
27 apr, 2016
52 / 54
Esercizi
Dal libro di testo (2a ed.)
Es.1 scrivere in pseudolinguaggio un frammento di codice tale
che il n.ro max di RdA sulla pila non sia determinabile
staticamente
Es.2 scrivere in pseudolinguaggio una funzione ricorsiva tale che
il n.ro max di suoi RdA sulla pila sia determinabile
staticamente
Es.3
Es.4
Es.5
Es.6 è più facile implementare la regola di scope statico o
dinamico? Motivare
Es.7
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
53 / 54
Riferimenti
Gabbrielli & Martini: Linguaggi di Programmazione,
McGraw-Hill 2a edizione. [cap. 7]
LdP.ITPS/[email protected]
Gestione della Memoria
27 apr, 2016
54 / 54