Allocazione contigua
La memoria principale deve supportare sia processi del SO che dell'utente.
Ed è solitamente divisa in due partizioni: una per il sistema operativo che contiene anche i vettori per gli interrupt e l'altra per i processi.
Quando la CPU chiede accesso ad un indirizzo logico, prima lo confronta con il registro limite(per evitare trap di addressing error), viene calcolato l'indirizzo fisico e si va in memoria.
Allocazione partizione multipla
Dynamic Storage-Allocation Problem
First fit: alloca nel primo hole che è grande abbastanza.
Best-fit: alloca nell’hole più piccolo che è abbastanza grande; deve quindi cercare nell'intera lista.
Worst-fit: alloca nell’hole più grande, nonostante non rispecchi le esigenze del processo; deve quindi cercare nell'intera lista.
First fit e Best-fit sono più efficienti in termini di velocità.
Frammentazione
Ed è solitamente divisa in due partizioni: una per il sistema operativo che contiene anche i vettori per gli interrupt e l'altra per i processi.
Quando la CPU chiede accesso ad un indirizzo logico, prima lo confronta con il registro limite(per evitare trap di addressing error), viene calcolato l'indirizzo fisico e si va in memoria.
Allocazione partizione multipla
Dynamic Storage-Allocation Problem
First fit: alloca nel primo hole che è grande abbastanza.
Best-fit: alloca nell’hole più piccolo che è abbastanza grande; deve quindi cercare nell'intera lista.
Worst-fit: alloca nell’hole più grande, nonostante non rispecchi le esigenze del processo; deve quindi cercare nell'intera lista.
First fit e Best-fit sono più efficienti in termini di velocità.
Frammentazione
La frammentazione può essere distinta in esterna ed interna.
La frammentazione esterna si manifesta quando in memoria c’è abbastanza spazio libero da allocare a un nuovo processo, ma non si presenta in maniera contigua.
Questo può essere un problema serio, e nel peggiore dei casi, ogni due processi potrebbe esserci un blocco di memoria inutilizzabile.
Poiché potrebbero rimanere frammenti molto piccoli - anche solo di un paio di byte - e per tenerne traccia se ne impiegherebbero molti di più, si tende ad evitare questo problema, dividendo la memoria in blocchi fissati. Si alloca per tutta la dimensione di questi, e la memoria occupata sarà leggermente più del necessario.
La differenza fra la memoria totale occupata dal blocco e quella realmente impiegata dal processo, viene chiamata frammentazione interna.
L’obiettivo della compattazione è quello di compattare la memoria libera in un unico blocco.
Questo tuttavia non è sempre possibile. Se la riallocazione è fatta in assembly o load time, ed è quindi statica questo non può essere fatto. In quanto gli indirizzi assegnati al codice saranno assoluti e non è possibile spostati eventuali blocchi.
Per quanto riguarda la riallocazione dinamica, è possibile spostare i blocchi, sostituendo solo l’indirizzo di base del registro a cui ci si riferisce, poiché gli indirizzi interni sono relativi.
Segmentazione
I programmatori non vedono necessariamente la memoria come un array di bytes, qualcuno contente dati e altro istruzioni.
Piuttosto preferiscono vederla come una collezione di segmenti, non necessariamente ordinati.
Un segmento è un'unità logica come: programma principale, procedura, funzione, metodo, oggetto, variabili locali, variabili globali, blocco comune, stack, tabella di simboli, array...
Ogni blocco di un programma ha degli indirizzi relativi, una volta che il programma viene eseguito è come se fossero messi in maniera contigua, pur essendo in spazi di memoria fisica non contigui.
Tuttavia la segmentazione non risolve del tutto il problema della frammentazione, poiché persiste, sebbene in una scala più piccola (la dimensione degli holes inutilizzabili è minore).
Un segmento è un'unità logica come: programma principale, procedura, funzione, metodo, oggetto, variabili locali, variabili globali, blocco comune, stack, tabella di simboli, array...
Ogni blocco di un programma ha degli indirizzi relativi, una volta che il programma viene eseguito è come se fossero messi in maniera contigua, pur essendo in spazi di memoria fisica non contigui.
Tuttavia la segmentazione non risolve del tutto il problema della frammentazione, poiché persiste, sebbene in una scala più piccola (la dimensione degli holes inutilizzabili è minore).
Architettura della segmentazione
Questo tipo di implementazione necessita di un hardware specifico, in quanto l'indirizzo logico consiste di due valori:
Normalmente quando un programma è compilato, il compilatore costruisce automaticamente segmenti che riflettono il programma di input.
Il programmatore può ora riferirsi a oggetti nel programma attraverso un indirizzo bidimensionale, ma l’attuale memoria fisica è ancora una sequenza unidirezionale di bytes.
Si deve quindi definire un’implementazione per una mappa bidimensionale degli indirizzi definiti dal programmatore che si riferisca a quella unidimensionale degli indirizzi fisici.
Questa mappatura è effettuata con una tabella di segmenti, in cui ogni entry nel tabella dei segmenti ha un una base e un limite.
La base del segmento contiene l’indirizzo fisico di partenza dove il segmento risiede in memoria, mentre il limite specifica la lunghezza del segmento.
Un indirizzo logico come detto prima, consiste in due parti: un numero di segmento(s) e un offset (d) all’interno dello stesso.
Tale offset deve essere un numero da zero al limite del segmento. Se non lo è, viene inviato un trap al sistema operativo (poiché l’indirizzo logico prova ad andare oltre il termine del segmento). Mentre quando l’offset è legale, viene sommato alla base del segmento per produrre l’indirizzo nella memoria fisica del byte desiderato. La tabella dei segmenti è essenzialmente un array di registri di basi (Segment table base register (STBR)) e di limiti (Segment table length register (STLR)).
/* segment numer s is legal if s < STLR */