Virtuaalimuisti on tapa hallita muistia siten, että jokainen prosessi näkee oman jatkuvan osoiteavaruuden, vaikka sen tiedot saattavat fyysisesti sijaita eri paikoissa. Nykyajan tietokoneissa tämä on vakiokäytäntö monissa teknologian sovelluksissa. Laitteisto (tietokoneen fyysinen osa, kuten prosessori tai näytönohjain) suorittaa koodia, mutta koodin ajo vaatii ohjelmistoja, jotka käyttävät tietokoneen muistia toimiakseen. Useimmat nykyiset koneet pystyvät suorittamaan useita ohjelmia samanaikaisesti eli harjoittavat moniprosessointia, jolloin sama fyysinen muisti ja muut resurssit jaetaan prosessien kesken. Tämä ei kuitenkaan tarkoita, että tietokoneeseen lisättäisiin lisää fyysisiä prosessoreita tai keskusmuistia (RAM) jokaista ajettavaa ohjelmaa kohden.

Miten virtuaalimuisti toimii

Virtuaalimuistin perusidea on tarjota sovellukselle virtuaalinen muistilohko: ohjelma luulee omistavansa yhtenäisen osoiteavaruuden. Tämä osoiteavaruus käännetään laitteiston ja käyttöjärjestelmän yhteistoiminnalla todelliseen, fyysiseen muistiin tai tarvittaessa levytilaan. Prosessorissa on tähän tarkoitukseen suunniteltu laitteiston osa, muistinhallintayksikkö (MMU, Memory Management Unit), joka muuntaa virtuaaliset osoitteet fyysisiksi. Muunnokset nopeutetaan tyypillisesti välimuistilla, jota kutsutaan käännöstauluvälimuistiksi (TLB).

Käyttöjärjestelmä ylläpitää taulukoita (sivutauluja, page tables), jotka kertovat, mihin fyysiseen muistikehykseen (page frame) kunkin prosessin sivu (page) on kartoitettu. Jokaisella prosessilla on oma virtuaaliosoiteavaruus, mikä tarjoaa eristyksen: prosessi ei voi vahingossa lukea tai muokata toisen prosessin muistia ilman erillisiä jakomekanismeja.

Sivutus ja sivunvaihto (paging ja page fault)

Suurin osa nykyaikaisista virtuaalimuistijärjestelmistä käyttää sivutusta. Muisti on jaettu yhtenäisiin lohkoihin eli sivuihin (tyypillisesti 4 KiB, mutta myös suurempia "huge pages" kuten 2 MiB tai 1 GiB). Kun prosessi yrittää käyttää virtuaaliosoitetta, MMU tarkistaa sivutaulusta, onko vastaava sivu jo fyysisessä muistissa. Jos ei ole, syntyy sivunvaihtotapahtuma (page fault) ja käyttöjärjestelmä joutuu lataamaan puuttuvan sivun levyltä (swap-alueelta tai tiedostojärjestelmästä) fyysiseen muistiin. Jos fyysinen muisti on täynnä, jotakin muuta sivua täytyy mahdollisesti siirtää takaisin levylle (swap-out) vapauttaakseen tilan.

Tätä toimintoa, jossa sivuja ladataan tarveperusteisesti levyn ja RAMin välillä, kutsutaan usein demand pagingiksi. Sivujen korvauspolitiikat (kuten LRU, FIFO, Clock) vaikuttavat siihen, mitkä sivut valitaan poistettaviksi. Jos koneessa on liian vähän muistia ja levyä käytetään jatkuvasti sivujen siirtämiseen, suorituskyky voi romahtaa ilmiöön, jota kutsutaan thrashingiksi.

Sivukoko, osoiteavaruudet ja arkkitehtuurierot

Sivukoko ja osoitteiden pituus vaikuttavat virtuaalimuistin toimintaan. 32-bittisissä järjestelmissä osoiteavaruus on rajoitetumpi kuin 64-bittisissä, joissa kukin prosessi voi periaatteessa käyttää valtavan suurta virtuaalista tilaa. Suuremmat sivut vähentävät sivutaulujen kokoa ja TLB-missien määrää, mutta voivat lisätä sisäistä hajautumista, kun muistia varataan isompina lohkoina.

Joissain järjestelmissä käytetään myös segmentointia (segmentation) tai segmentoinnin ja sivutuksen yhdistelmiä. Monet nykyaikaiset käyttöjärjestelmät ja prosessorit tukevat useita sivukokoja ja keinoja optimoida suorituskykyä.

Edut ja haitat

  • Edut: prosessien eristäminen ja turvallisuus, helppo ohjelmointi ilman tarvetta huolehtia fyysisestä muistinhallinnasta, mahdollisuus käyttää suurempaa kuvitteellista muistia kuin fyysinen RAM (overcommit), muistin jakaminen (shared libraries) ja copy-on-write -tekniikat tehokkaaseen resurssien käyttöön.
  • Haitat: vasteajan ennustettavuuden heikkeneminen (erityisesti reaaliaikaisissa tai sulautetuissa järjestelmissä), lisäyhtälöt ja ylikuorma MMU- ja OS-käsittelyissä, mahdollisuus thrashingiin, sekä levyn I/O:n aiheuttama hitautta ja SSD-levyjen kulumista, jos swap:ia käytetään paljon.

Käyttötapaukset ja poikkeukset

Suurin osa yleiskäyttöisistä käyttöjärjestelmistä (esim. Linux, Windows, BSD) käyttää virtuaalimuistia ja swap-tilaa tai -tiedostoja hallitakseen muistia tehokkaasti. Toisaalta tietyt järjestelmät, kuten monet sulautetut järjestelmät, eivät käytä virtuaalimuistia, koska ne vaativat hyvin ennustettavaa ja nopeaa vasteaikaa ilman levyltä lataamisen tuomaa viivettä. Reaaliaikajärjestelmissä virtuaalimuistin ominaisuudet voidaan usein poistaa päältä tai suunnitella niin, että kaikki käytettävät sivut ovat ennakolta varattuja ja pysyvästi RAMissa.

Yhteenveto

Virtuaalimuisti on keskeinen tekniikka, joka tekee monen ohjelman samanaikaisesta suorittamisesta turvallista ja tehokasta tarjoamalla jokaiselle prosessille oman virtuaalisen osoiteavaruuden. Se yhdistää laitteiston (MMU, TLB) ja ohjelmiston (käyttöjärjestelmät) toiminnot sivutuksen, sivunvaihdon ja sivutaulujen avulla. Hyvin suunniteltuna se parantaa resurssien käyttöä ja järjestelmän joustavuutta, mutta se voi myös aiheuttaa suorituskykyongelmia ja ennustettavuuden puutetta tietyissä käyttötapauksissa.