Razporejevalnik opravil skrbi za časovno ločitev procesov, torej za to, da si naenkrat lasti procesor le en proces. Poleg tega moramo procese ločiti tudi prostorsko, tako da uporabljajo le kos pomnilnika, ki jim je dodeljen, ne pa tudi prostora, dodeljenega drugim procesom. Celo če predpostavimo, da bi programi poskušali sodelovati drug z drugim, ne moremo dopustiti, da bi napaka v enem od njih poškodovala druge. Naloge operacijskega sistema v zvezi z dodeljevanjem prostora poznamo pod imenom upravljanje pomnilnika (angl. memory management).
Vsak proces v zverinjaku potrebuje svoj kos pomnilnika, torej prostor, v katerem bo izvajal svojo kodo ter vanj shranjeval spremenljivke in rezultate. Lahko si zamislimo, da del tega prostora zaseda programski segment, ki shranjuje programske ukaze v strojnem jeziku in iz katerega lahko samo beremo, ter podatkovni segment, ki obsega vse spremenljivke, uporabljene v programu, in v katerega je mogoče tudi pisati. Podatkovni segment se res razlikuje od procesa do procesa; programski pa ne nujno: če dva procesa poganjata isto programsko kodo, Unix varčuje s prostorom in samodejno poskrbi, da je programski segment naložen v pomnilnik samo enkrat.
Učinkovito ravnanje s prostorom je pomembno, saj je pomnilnik drag. Včasih ga nimamo dovolj, da bi naenkrat držali v pomnilniku vse programe, ki se izvajajo, še posebej, če je med njimi kak velik program, denimo strežnik X. Unix težavo zaobide s tehniko, ki jo poznamo kot virtualni pomnilnik. Jedro ne poskuša držati v pomnilniku celotne kode in podatkov za posamezni proces, ampak samo relativni manjši delovni nabor. Preostanek pomnilniške slike procesa je shranjen na posebnem prostoru na disku (tako imenovani izmenjalni prostor).
V preteklosti, ko so imeli računalniki malo pomnilnika, je ,,včasih`` iz prejšnjega odstavka pomenilo ,,skoraj vedno``. Dandanes pomnilnik ni več tako drag, kot je bil nekdaj, in celo računalniki s spodnjega konca lestvice ga premorejo kar precej. V sodobnih enouporabniških računalnikih, ki imajo 64 ali več megabajtov pomnilnika, je mogoče poganjati okna X in navadno paleto opravil, ne da bi bilo treba uporabiti izmenjalni prostor.
V prejšnjem razdelku smo stvari namenoma poenostavili. Drži, da programi obravnavajo pomnilnik kot dolgo vrsto pomnilniških naslovov, ki lahko presega fizični pomnilnik, in da to slepilo vzdržujemo z diskovnim izmenjavanjem. Vendar pa premore običajni računalnik nič manj kot pet različnih vrst pomnilnika, in razlike med njimi so pomembne, kadar moramo iz računalnika iztisniti kar največ. Da bi resnično razumeli, kaj se dogaja v računalniku, moramo razumeti tudi, kako delujejo posamezne vrste pomnilnika.
Pet vrst pomnilnika je: procesorski registri, notranji predpomnilnik (na samem čipu), zunanji predpomnilnik (na ločenem čipu), glavni pomnilnik ter disk. Razlog za toliko različnih vrst pomnilnika je en sam: hitrost se plača. Našteli smo jih od najhitrejšega do najpočasnejšega ali od najdražjega do najcenejšega. Registri so najhitrejša in najdražja oblika pomnilnika, uporabimo pa jih lahko približno milijardkrat na sekundo. Disk je najpočasnejša in najcenejša oblika; podatke na njem lahko uporabimo približno stokrat na sekundo.
Sledi seznam z vrednostmi za običajni namizni računalnik, kot so bile aktualne spomladi leta 2000. Hitrost in velikost bosta s časom naraščali, cene pa se bodo nižale, vendar lahko pričakujete, da bodo razmerja med njimi ostala bolj ali manj enaka. In ta razmerja določajo pomnilniško hierarhijo.
Velikost 13.000 MB Hitrost: 100 KB/s
Velikost 256 MB Hitrost: 100 MB/s
Velikost 512 KB Hitrost: 250 KB/s
Velikost 32 KB Hitrost: 500 KB/s
Velikost 28 B Hitrost: 1000 KB/s
Celotnega računalnika ne moremo zgraditi iz najhitrejše vrste pomnilnika. Dosti predrago bi bilo -- in celo če to ne bi bilo res, hitri pomnilnik ni trajen. Brž ko izključimo napajanje, izgubi svojo vrednost. Zato morajo računalniki imeti tudi neko vrsto trajnega pomnilnika -- npr. disk -- ki ohrani svojo vrednost tudi, ko izklopimo napajanje. Med hitrostjo procesorjev in hitrostjo diskov pa zeva velikanski prepad. Srednje tri ravni v hierarhiji procesorjev -- notranji predpomnilnik, zunanji predpomnilnik in glavni pomnilnik -- so zgolj zato, da premagajo ta prepad.
Linux in drugi Unixi uporabljajo navidezni pomnilnik. To pomeni, da se operacijski sistem vede, kot da bi imel na razpolago dosti več pomnilnika, kot pa ga je dejansko na voljo. Fizični pomnilnik se obnaša kot vrsta ,,oken`` na mnogo večjem ,,navideznem`` pomnilniku, katerega večina je v slehernem trenutku shranjena na disku, na posebnem prostoru, imenovanem izmenjalni prostor. Ne da bi se uporabniški procesi tega zavedali, operacijski sistem sproti prenaša bloke podatkov (takemu bloku pravimo tudi page, slov. stran) iz pomnilnika na disk in nazaj, in tako ustvarja iluzijo velikega pomnilnika. Končni rezultat je, da je tak navidezni pomnilnik dosti večji, pa niti ne dosti počasnejši od fizičnega.
Koliko počasnejši je navidezni pomnilnik od fizičnega, je odvisno od tega, kako dobro algoritmi za izmenjevanje v operacijskem sistemu predvidijo porabo pomnilnika. Na srečo večina sklicev na pomnilniške lokacije, ki si sledijo v kratkem času, bere oziroma piše na pomnilniške lokacije, ki so tudi prostorsko blizu skupaj. Ta lepa lastnost je znana kot lokalnost ali lokalnost sklicevanja. Če bi, nasprotno, bili pomnilniški sklici naključno raztreseni po celotnem pomnilniškem prostoru, bi morali ob vsakem sklicu na pomnilniško lokacijo prebrati podatke z diska, in navidezni pomnilnik bi bil enako počasen kakor disk. Ker pa programi kažejo lokalnost, lahko operacijski sistem opravi pomnilniška sklicevanja z razmeroma malo branja z diska.
Izkustveno je bilo ugotovljeno, da je najučinkovitejša metoda za široko paleto vzorcev rabe pomnilnika nadvse preprosta: algoritem se imenuje LRU (angl. Least Recently Used, ,,tisti, ki najdlje ni bil rabljen``). Mehanizem za navidezni pomnilnik naloži diskovni blok v svoj delovni nabor, ko se pokaže potreba po tem. Če fizičnega pomnilnika ni več na voljo, iz njega zbriše blok, ki najdlje ni bil rabljen. Vse različice Unixa, pa tudi večina drugih operacijskih sistemov, ki uporabljajo navidezni pomnilnik, uporabljajo to ali ono različico algoritma LRU.
Navidezni pomnilnik je prvi člen pri premagovanju prepada med hitrostjo diska in procesorja, in ga izrecno upravlja operacijski sistem. Podoben, čeprav nekaj manjši prepad zija tudi med hitrostjo glavnega pomnilnika in hitrostjo procesorja. Notranji in zunanji predpomnilnik rešujeta to težavo s tehniko, ki je podobna pravkar opisani.
Tako kot se fizični glavni pomnilnik obnaša kot vrsta oken v izmenjalnem prostoru na disku, se tudi zunanji predpomnilnik obnaša kot okna v glavnem pomnilniku. Zunanji predpomnilnik je hitrejši od glavnega (250 milijonov dostopov na sekundo proti 100 milijonom), a manjši. Računalnik -- natančneje, upravljalnik pomnilnika -- izvaja v njem algoritem LRU na blokih podatkov iz glavnega pomnilnika. Iz zgodovinskih vzrokov se tu pomnilniška enota imenuje ,,vrstica`` (angl. line) namesto ,,stran`` (angl. page).
Nismo še končali. Še zadnji korak pospešitve je notranji predpomnilnik. Ta izvaja algoritem LRU na blokih podatkov iz zunanjega pomnilnika. Je še hitrejši in še manjši -- tako majhen pravzaprav, da je kar del mikroprocesorskega čipa.
Če bi radi napisali čim hitrejše programe, je dobro, da poznamo te podrobnosti. Programi tečejo tem hitreje, čim večjo lokalnost imajo, saj je tedaj algoritem LRU bolj učinkovit. Najenostavnejša pot, po kateri dosežemo, da so programi hitri, je, da so majhni. Če programa ne zavira kopica branj in pisanj z diska ali omrežja, bo navadno tekel s hitrostjo najmanjšega predpomnilnika, v katerega ga lahko shranimo.
Če ne moremo napraviti celotnega programa tako majhnega, se včasih splača potruditi in časovno kritične dele napisati tako, da so čim bolj lokalni. Podrobnosti tehnik za taka fina uglaševanja presegajo ta navodila; do takrat, ko jih boste potrebovali, boste verjetno že dovolj domači s prevajalnikom, da boste mnoge od njih odkrili sami.
Celo če imamo na voljo dovolj fizičnega pomnilnika, da diskovno izmenjevanje ni potrebno, ima del operacijskega sistema, zadolžen za upravljanje pomnilnika, še vedno pomembno nalogo. Paziti mora na to, da lahko vsak program spreminja le svoj podatkovni segment -- preprečiti mora torej, da bi okvarjen ali zlonameren program poškodoval podatke, ki pripadajo drugemu programu. Zato vodi knjigovodstvo o uporabljenih podatkovnih in programskih segmentih. Vsakič, ko program zahteva dodatni pomnilnik ali pa sprosti pomnilnik (slednje se navadno zgodi, ko program konča delo), mora posodobiti tabelo.
Tabela se uporablja za posredovanje ukazov specializiranemu kosu strojne opreme, imenovanemu MMU (angl. memory management unit, enota za upravljanje pomnilnika). Sodobni mikroprocesorji imajo enoto MMU že integrirano na sam procesorski čip. Enota MMU ima možnost, da ,,ogradi`` posamezna območja pomnilnika, tako da so poskusi poseganja zunaj tega območja zavrnjeni in izzovejo posebno vrsto prekinitve.
Če ste v Unixu že kdaj naleteli na napako ,,Segmentation fault, core
dumped`` ali kaj podobnega -- to je to. Proces je poskusil poseči po
delu pomnilnika zunaj svojega podatkovnega segmenta, operacijski sistem pa mu je to preprečil in ga prisilno končal. Tako vedenje
je posledica napake v programu -- datoteka core
s pomnilniško
sliko procesa ob smrti, ki jo operacijski sistem ob tej priložnosti zapiše
na disk, je diagnostična informacija, ki naj bi bila v pomoč
programerju pri iskanju napake.
Poleg omejitve pomnilnika je še en vidik varovanja procesov pred drugimi procesi. Nadzor želimo imeti tudi nad dostopom do datotek, tako da okvarjen ali zlonameren program ne more poškodovati katere od ključnih datotek na disku. Zato pozna Unix dovolilnice za datoteke, o katerih bomo več povedali pozneje.