Gestione della Memoria - LACAM
Transcript
Gestione della Memoria - LACAM
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