Gestione della memoria centrale La memoria principale è una risorsa essenziale per un elaboratore Un programma per essere eseguito deve risiedere all'interno della memoria principale e lo stesso discorso vale per i dati su cui esso opera Se molti processi devono essere eseguiti contemporaneamente, si dovrà trovare un meccanismo per permettere a questi processi di condividere l'uso della memoria principale Gestione della memoria centrale Esistono due tecniche fondamentali per la gestione della memoria principale: tecniche non virtuali (memoria reale): tutta l’immagine* di un processo attivo deve essere caricata in memoria principale tecniche virtuali (memoria virtuale): un processo attivo può avere solo una parte della sua immagine caricata in memoria principale *immagine di un processo: programma che il processo sta eseguendo Tecniche non virtuali Data la memoria principale fisicamente esistente all'interno di un elaboratore, come dobbiamo allocarla ai processi che devono essere eseguiti? Consideriamo dapprima il caso, molto semplice, di un sistema mono-programmato in cui in ogni istante esiste un solo processo di utente In realtà abbiamo anche dei processi di sistema, e quindi dovremo destinare una parte della memoria alla parte residente del sistema operativo e una parte al processo utente Sistema mono programmato La memoria è divisa in due partizioni: una destinata al SO; l’ altra al processo utente Di solito si sceglie di destinare al sistema operativo le prime o le ultime celle della memoria 0 X X+1 Sistema Operativo S.O. processo utente N Tecniche non virtuali Veniamo ora al caso di un sistema multiprogrammato in cui più programmi utente P1, P2…Pn sono eseguiti contemporaneamente. Per ciascuno di questi processi il programma ed i dati corrispondenti devono essere in memoria principale Dobbiamo suddividere la memoria non occupata dal SO in n partizioni: una per ciascuno degli n processi Tecniche non virtuali Nel caso di un sistema con partizioni di memoria multiple sorgono nuovi problemi di gestione per il sistema operativo Quante partizioni creare e di quali dimensioni? Le partizioni sono create una volta per tutte al momento della configurazione del sistema o possono essere modificate a seconda delle necessità correnti? Come si sceglie la partizione in cui caricare l'immagine di un processo? Come si tiene traccia di dove sono stati caricati i processi? Come si proteggono i programmi tra di loro? Tecniche non virtuali Per tener traccia delle zone di memoria in cui sono stati caricati i programmi è sufficiente mantenere nel descrittore di ciascun processo l'indirizzo iniziale della partizione in cui esso è caricato Quando si hanno più processi in memoria si deve fare in modo che nessuno di essi possa operare in una zona di memoria destinata ad un altro Ad ogni processo deve essere consentito di leggere e scrivere solo all'interno della sua partizione in modo da non danneggiare l'esecuzione degli altri Tecniche non virtuali Si possono utilizzare due registri per delimitare la partizione di memoria del processo in esecuzione e, ogni volta che si vuole fare un accesso in memoria, si dovrà controllare che l’indirizzo prodotto sia valido, cioè all’interno della partizione in cui è caricata l’immagine del processo Indirizzo iniziale partizione Indirizzo finale partizione Sistema Operativo S.O. processo utente Tecniche non virtuali Suddivisione della memoria in partizioni fisse partizioni variabili S.O. 200KB 100KB 100KB S.O. area libera 400 KB S.O. 50 KB area libera 350 KB Tecniche non virtuali Le tecniche di partizioni (sia fisse che variabili) provocano uno spreco di spazio di memoria, noto con il nome di frammentazione: Con le partizioni fisse, all’interno di ogni partizione ci sara’ uno spazio non utilizzato (difficilmente un programma ha le stesse dimensioni di una partizione): frammentazione interna Con le partizioni variabili, dopo un certo numero di allocazione e deallocazione di processi, si formeranno un certo numero di porzioni di memoria libere (“buchi”), di dimensioni insufficienti a contenere un processo: frammentazione esterna Tecniche virtuali Uno degli obiettivi di un sistema operativo multiprogrammato, in particolare in ambiente multiutente, è quello di nascondere il più possibile a ciascun processo (a ciascun utente) la presenza degli altri processi (utenti) che stanno condividendo le risorse di calcolo Compito del sistema operativo è quello di fornire ad ogni singolo processo una visione astratta in cui esso ha una macchina virtuale interamente a sua disposizione Tecniche virtuali Nel caso della gestione del processore abbiamo visto che la tecnica di alternare l'esecuzione fa sì che ogni utente abbia l'impressione che il suo programma sia sempre in esecuzione Per quanto riguarda la gestione della memoria, il problema è più complesso. Si vuole che ogni utente possa, almeno in linea di principio, scrivere programmi grandi almeno quanto la memoria reale e che questi programmi possano essere eseguiti contemporaneamente ad altri Tecniche virtuali In alcuni casi si vogliono addirittura nascondere agli utenti le dimensioni della memoria fisica e fare in modo che essi possano scrivere dei programmi di dimensione qualunque, anche molto più grandi dello spazio di memoria effettivamente esistente sulla macchina hardware In questo modo, tra l'altro, è possibile che un utente esegua i suoi programmi su macchine differenti, senza doversi preoccupare delle dimensioni delle loro memorie centrali Tecniche virtuali Questa visione astratta della memoria prende il nome di memoria virtuale e i programmi di sistema che la realizzano prendono il nome di gestori della memoria virtuale La tecnica fondamentale per la gestione della memoria virtuale consiste nel caricare le immagini dei processi nella memoria centrale a pezzi Tecniche virtuali Supponiamo di avere a disposizione una memoria principale (spazio utente) di 1 MByte e di voler eseguire simultaneamente due programmi che richiedono entrambi 1 Mbyte Le tecniche di gestione della memoria a partizioni fisse o variabili non ci permettono di eseguire contemporaneamente questi due programmi perché le loro immagini non possono essere caricate entrambe nella memoria principale Tecniche virtuali Per eseguire un processo non è necessario caricare completamente in memoria la sua immagine È sufficiente caricare in memoria principale solo quelle parti del programma e dei dati che servono durante una certa fase dell'elaborazione; le altre parti possono essere tenute su un supporto di memoria secondaria In questo modo la memoria potrà essere condivisa da più processi in quanto, in ogni istante, solo una parte di ognuno di essi risiederà in memoria Tecniche virtuali Per gestire la memoria in modo virtuale, è necessario avere: La memoria principale in cui tenere solo i programmi, o i pezzi di programmi, che servono in un certo istante. Un supporto di memoria secondaria in cui mantenere tutte le immagini dei processi che verranno caricate di volta in volta nella memoria principale (solitamente si utilizzano come supporti di memoria secondaria i dischi rigidi perché sono necessari dei supporti veloci e con accesso diretto, per fare in modo che il tempo richiesto per i caricare programmi dalla memoria secondaria a quella principale non sia troppo alto) Tecniche virtuali Si possono tenere in memoria solo alcune parti delle immagini dei processi, purché si sia sempre in grado di caricare le altre parti quando servono. Questa è proprio l'idea che sta alla base delle tecniche di gestione a pezzi e, in particolare, della tecnica di paginazione a richiesta (demand paging) Nella paginazione l'immagine di un processo viene suddivisa in blocchi (pagine), tutte della stessa dimensione, che vengono caricate all'interno della memoria principale in modo indipendentemente, anche in posizioni non contigue. La contiguita’ del processo viene realizzata da una Tabella delle Pagine che memorizza per ogni pagina del processo la sua posizione in RAM (se e’ caricata). Tecniche virtuali Se durante l’esecuzione del processo, la CPU fa riferimento ad un indirizzo che appartiene ad una pagina non caricata in RAM, il SO provvede a mettere il processo in stato d’attesa e a far partire il caricamento della pagina richiesta, dopo di che’ il processo puo’ riprendere la sua esecuzione. Nella paginazione a domanda, esiste ancora il problema della frammentazione, che e’ pero’ limitato al fatto che l’ultima pagina di ogni processo e’ solo parzialmente occupata (mediamente si puo’ considerare uno spreco pari a circa ½ pagina per ogni processo). Tecniche virtuali Per avere un sistema di gestione della memoria basato sul demand paging anche la memoria principale dell'elaboratore deve essere suddivisa in un certo numero di blocchi, tutti delle stesse dimensioni (uguali alla dimensione della pagina) RAM P1/2 P3/1 P2/1 P1/1 P2/2 P1/2 P1/3 P1/3 P3/1 P3/2 P2/1 P2/2 P2/3