Sei sulla pagina 1di 40

Gestione della memoria

Il gestore della memoria ha la funzione


di allocare (ASSEGNARE) la memoria e
partizionarla (DIVIDERLA) tra i vari
programmi
Processi e memoria

• Tutti i processi in esecuzione necessitano


della memoria centrale per memorizzare:
– le istruzioni che fanno parte del codice del
programma
– i dati su cui operano
Gestione della memoria centrale
• Il sistema operativo permette l’esecuzione
contemporanea di più processi e tutti i processi
pronti dovrebbero avere tutto il programma o
almeno le prossime istruzioni caricate nella
memoria.
• Se lo spazio totale occupato dai processi supera
la dimensione della memoria centrale, non tutti i
processi possono risiedere per intero nella
memoria centrale

• Normalmente la quantità di memoria non è


sufficiente a contenere tutti le istruzioni e tutti i
dati di tutti i processi gestiti.
Gestione della memoria centrale

• La memoria deve essere gestita con molta


attenzione ed efficienza caricando solo i
dati e le istruzioni che devono essere
modificate ed eseguite. Le altre parti
devono essere spostate sul disco rigido per
poter essere caricate quando necessario.
• La memoria virtuale e’ un sistema per
aumentare lo spazio di memoria disponibile
Gestione della memoria centrale
• Partizionamento della memoria e del suo spazio di indirizzi.
• Tecniche di partizionamento:
– Segmentazione: suddivide la memoria centrale in segmenti di lunghezza
variabili contenenti parti di un programma logicamente correlati tra di loro
– Paginazione: suddivide memoria e programmi in pagine di lunghezza fissa;
i programmi vengono caricati in memoria anche in pagine non contigue
• NON sono tecniche alternative. Spesso sono applicate
contemporaneamente.
• Sia nel caso della paginazione, sia in quello della segmentazione, il
gestore della memoria offre al programma applicativo la visione di
una memoria virtuale
Indirizzi virtuali
• Indirizzi simbolici
– nel codice sorgente del programma gli indirizzi sono
espressi in modo simbolico
• Es. identificatori di variabili nei linguaggi ad alto livello
• Indirizzi logici
– l'assemblatore (o il compilatore) trasforma gli indirizzi
simbolici in valori binari che non rappresentano ancora
però un vero indirizzo di memoria.
– In genere gli indirizzi logici sono calcolati a partire da un
indirizzo iniziale che vale in genere zero (indirizzi binari
logici relativi a zero)
• Indirizzi virtuali
– il linker effettua la traduzione del codice sorgente in
linguaggio macchina e genera indirizzi che non sono ancora
però riferimenti fisici alla memoria
Rilocazione
• Indirizzi fisici
– Gli indirizzi virtuali possono essere finalmente
tradotti in indirizzi di memoria fisica.
– Questa operazione di traduzione, in sostanza,
costituisce uno dei compiti fondamentali del
gestore della memoria.
• La traduzione degli indirizzi virtuali in indirizzi
fisici è definita rilocazione
Rilocazione e protezione
• Per evitare che un processo faccia riferimento a
zone di memoria appartenenti ad altri processi
molti sistemi utilizzano registri speciali di
protezione(registri limite) per controllare ed
eventualmente inibire riferimenti non autorizzati.
• Questi metodi sono ottenibili con sistemi dotati
di MMU e i registri base e limite ad esempio
possono essere considerati elementi della MMU
del sistema.
Memory Management Unit (MMU)
• E' un componente hardware che gestisce le
richieste di accesso alla memoria generate
dalla CPU
• Una Memory Management Unit (MMU) ha
vari compiti, tra cui la traduzione degli indirizzi
virtuali in indirizzi fisici, la protezione della
memoria, il controllo della cache della CPU ...
• La MMU è integrata nei moderni
microprocessori
Allocazione
• Tecnica con cui il SO concede ed assegna memoria ai
programmi.
• Allocazione statica
– processi caricati in memoria che sono allocati una
sola volta e sono revocati dalla memoria solo al
termine dell'esecuzione
• Allocazione dinamica
– processi che in esecuzione possono vedersi
revocata e riallocata la memoria più volte, in
genere con operazioni di swapping *da e per la
memoria secondaria.
Swapping
Swapping è un meccanismo in cui
un processo può essere spostato
temporaneamente dalla memoria
principale ad una memoria di
supporto di tipo secondario e poi
riportato in memoria per
l'esecuzione.
Rilocazione statica
• La rilocazione statica è quel meccanismo per cui il
caricatore (del programma) del SO, dopo aver letto
l'intero programma e prima di porlo in esecuzione,
rialloca in memoria tutto il codice del programma,
adattando gli indirizzi virtuali alle posizioni attualmente
disponibili nella memoria fisica.
• Il caricatore in questo caso viene detto rilocante; dopo
la rilocazione statica il programma in memoria ha
assunto riferimenti di memoria fisica che non potranno
più cambiare per tutta la durata dell'esecuzione.
Rilocazione dinamica
• Il SO rialloca il codice durante
l'esecuzione del programma, utilizzando
elementi di MMU.
• A differenza della rilocazione statica la
rilocazione dinamica permette ai
programmi di essere caricati in aree di
memoria differenti durante l'esecuzione;
sarà sufficiente modificare le
informazioni contenute nel meccanismo
hardware che realizza la funzione di
rilocazione (meccanismo di MMU).
Memoria e multiprocessing
• Più processi sono attivi contemporaneamente
• Ogni processo necessita di memoria per le
istruzioni e i dati
• Il Sistema Operativo deve gestire
– la protezione dei dati e delle istruzioni relativi a
ogni singolo processo
– il riutilizzo delle zone di memoria non più utilizzate
dai processi
Memoria suddivisa in settori
• A ogni processo viene
assegnato un settore di
memoria compreso fra
un indirizzo iniziale e
uno finale
• Il gestore della memoria
gestisce una tabella di
indirizzi in cui associa ad
ogni processo il suo
indirizzo iniziale e finale
Settori: indirizzi
• Indirizzo logico (generato staticamente)
– Il compilatore assume che l'indirizzo di partenza
per i dati e le istruzioni sia l'indirizzo 0 (zero)
• Indirizzo fisico (dove
(d si trova realmente in memoria
fisica, generato dinamicamente)
– In fase di esecuzione gli indirizzi vengono traslati
(convertiti) sommando l'indirizzo di partenza del
settore associato al processo (operazione
effettuata dalla MMU)
– Un indirizzo di memoria contiene una parte che
identifica un settore (indirizzo logico) e una parte
che specifica l'offset *entro il settore.
Settori: problemi
• Il problema principale è la frammentazione
della memoria:
– quando termina un processo viene rilasciato il suo
settore di memoria che può essere associato a un
nuovo processo che richiede una quantità di
memoria minore o uguale a quella rilasciata
– le parti inutilizzate dei settori portano a una
progressiva frammentazione (potrebbe essere
disponibile memoria sufficiente per allocare un
processo ma non in un settore continuo)
Strategie di allocazione
• Le strategie di allocazione stabiliscono il criterio scelto per creare o
scegliere le partizioni per i programmi che le richiedono.
• First fit
– Individua la prima partizione atta a contenere il programma e,
quindi, tra le partizioni disponibili, viene scelta quella con indirizzi
più bassi. Tale tecnica è efficiente per mantenere compattate le zone
rilasciate.
• Best first
– Ricerca nella tabella la partizione più piccola atta a contenere il
programma. In questo modo si vengono a creare numerose
partizioni libere molto ristrette e quindi si aumenta la
frammentazione.
• Worst fit
– Tra le partizioni libere atte a contenere il programma, sceglie quella
più ampia, per attenuare l'effetto della frammentazione.
Compattazione
• In alcuni casi la riduzione della
frammentazione si può ottenere con una
tecnica detta di compattazione della memoria.
• In questo modo il SO predispone un algoritmo
che periodicamente controlla lo stato della
memoria e quando necessario interrompe le
esecuzioni per compattare in modo contiguo
tutta la memoria allocata eliminando i buchi e
aggiornando la tabella della memoria.
Paginazione
• La memoria principale viene «vista» dal
processore come un insieme di settori aventi
tutti la stessa dimensione predefinita.
• Il sistema operativo assegna a ogni processo
in esecuzione un numero di pagine sufficiente
per contenere il codice e i dati.
• Le pagine non sono necessariamente
contigue.
Tabella delle pagine
Organizzazione in pagine
Traslazione degli indirizzi

• Per la traslazione degli indirizzi ogni processo è


dotato di una tabella di corrispondenza fra
pagina logica e pagina fisica
MMU e paginazione
• Il compito della MMU è più complesso
• Per la traduzione da indirizzo logico a indirizzo
fisico:
– si individua la pagina logica
– poi si individua la corrispondente pagina fisica
Dimensione delle pagine
• Se la dimensione di una pagina è una potenza di 2 gli indirizzi vengono di
fatto spezzati in due:
– i primi bit determinano la pagina
– i successivi determinano l’indirizzo interno alla pagina (offset)
• La traslazione sostituisce i bit relativi alla pagina fisica a quelli relativi alla
pagina logica e lascia inalterati i restanti bit
• Esempio: indirizzo logico (pagine da 8Kb)
– 0001 - 0001 0001 0000 (pagina 1, indirizzo 0x1110)
• Indirizzo fisico:
– 0100 – 0001 0001 0000 (pagina 4, indirizzo 0x1110)
Il compito della MMU
Frammentazione
• Il problema della frammentazione è risolto
• Al termine di un processo vengono “liberate”
tutte le pagine utilizzate da questo
• Un nuovo processo ha a disposizione tutte le
pagine rimaste “libere”
Processi in memoria
Dimensione della tabella delle pagine
• Gli attuali processori indirizzano memorie di
grandi dimensioni e la dimensione della
tabella delle pagine risulta troppo grande per
essere contenuta nella MMU
• Per esempio con RAM da 4Gb e pagine da 4Kb
(sia Windows che Linux utilizzano pagine da
4Kb) si hanno più di un milione di pagine
• La tabella viene quindi memorizzata nella
RAM e solo una copia di una piccola parte di
questa risiede nella MMU
Memoria virtuale
• I processi attivi in un sistema operativo multitasking sono
molti ed è probabile che il numero complessivo delle pagine
richieste da tutti i processi sia superiore al numero di pagine
di memoria effettivamente disponibili
• Praticamente tutti i moderni sistemi operativi
implementano la tecnica della “memoria virtuale”: il gestore
della memoria mette a disposizione un numero di pagine
superiore a quelle presenti nella memoria fisica
• Alcune pagine sono salvate temporaneamente nella
memoria di massa (normalmente hard disk)
• La memoria di massa utilizzata a questo scopo è
comunemente chiamata, in ambiente Unix-Linux, swap o
spazio di swap, mentre, in ambiente Windows, è chiamata
file di paging.
Pagine logiche e fisiche
Prestazioni
• La memoria di massa ha tempi di accesso
estremamente più lenti della memoria centrale:
– memoria centrale 50-60 nanosecondi (circa 10 -8
secondi)
– memoria di massa 2-4 microsecondi (circa 10 -3
secondi)
• E’ necessario quindi ridurre al minimo le
operazioni di swapping (spostamento delle
pagine dallo spazio di swap alla memoria fisica)
Località del codice
• Normalmente un processo in ogni fase della sua
esecuzione fa riferimento a istruzioni e dati
contenuti in poche pagine di memoria contigue.
• Località delle istruzioni: l’esempio classico è un
ciclo che ripete più volte istruzioni consecutive
• Località dei dati: la struttura più comunemente
utilizzata è l’array in cui i dati sono contigui in
memoria
Tabella delle pagine
• La MMU trasla gli indirizzi
• Se la pagina non è
presente in memoria
(page-fault) il processo
viene posto in stato di
wait in attesa che la
pagina venga caricata in
memoria
• Il gestore della memoria
recupera la pagina,
aggiorna la tabella delle
pagine e riporta il
processo in ready
Page-fault
• Ogni page fault rallenta drasticamente
l’esecuzione di un processo che deve transitare
dallo stato di wait e deve attendere il
caricamento della pagina dalla memoria di massa
• Se non sono disponibili pagine libere in memoria
centrale è necessario sostituire una pagina dello
stesso processo (allocazione locale) o di un altro
processo (allocazione globale)
Politiche per la gestione del page-fault
• FIFO (First In First Out)
– la pagina da rimuovere è la prima che è stata caricata. L’idea è che le
pagine “vecchie” non vengano più utilizzate in futuro
• LRU (Least Recently Used)
– la pagina da rimuovere è quella inutilizzata da più tempo. L’idea è che
se non è utilizzata da molto tempo non verrà più utilizzata
• LFU (Least Frequently Used)
– la pagina da rimuovere è quella meno utilizzata. L’idea è che se è stata
poco utilizzata sarà poco utilizzata anche in futuro
Strumenti per la gestione delle
politiche
• FIFO
– è sufficiente memorizzare per ogni pagina il momento del caricamento in
memoria
• LRU
– deve essere memorizzato il tempo ad ogni accesso alla pagina
• LFU
– deve essere memorizzato un contatore incrementato ad ogni accesso alla
pagina
– per semplificare la gestione si utilizza un bit che viene settato se di fa
accesso a una pagina (i bit vengono periodicamente azzerati) la politica
diventa quindi NRU (Not Recently Used)
Swapping
• Se una pagina viene eliminata dalla memoria
centrale deve essere copiata sulla memoria di
massa
• Un “dirty bit” settato se la pagina viene
modificata può essere utilizzato per evitare
questa fase di riscrittura su disco (molto
spesso per le pagine di codice)
Codice condiviso
• Molti sistemi operativi prevedono l’uso di
funzioni condivise fra vari processi
– linux – shared objects
– windows – DLL (Dynamic Link Library)
• Queste funzioni vengono caricate solo se
utilizzate e in questo caso condivise fra i vari
processi
Windows e Linux

Potrebbero piacerti anche