Muistinhallinta

**Muistinhallinta** () on keskeinen osa käyttöjärjestelmän ja tietokoneohjelman toimintaa tietokoneen resurssien hallinnassa ja muistin käsittelyssä.

Muisti voidaan jakaa käyttöjärjestelmän ja käyttäjän sovelluksien kesken, sekä käyttäjäavaruus voidaan jakaa edelleen useiden prosessien käyttöön. Muistin jakaminen dynaamisesti on muistinhallinnan tehtävä.

## Taustaa

Tyypillisesti ohjelma on suoritusvalmiina massamuistilla. Kun ohjelmaa suoritetaan se ladataan tietokoneen muistiin prosessiksi. Tietokoneen muisti voi alkaa osoitteesta nolla, mutta ohjelman ensimmäisen osoitteen ei tarvitse olla nolla. Jos tiedetään ennalta mihin osoitteeseen ohjelma ladataan se voi käyttää absoluuttisia osoitteita. Ohjelma voi olla uudelleensijoitettava, jolloin ohjelman muistiviittaukset saavat lopullisen arvonsa latauksen yhteydessä. Osoitteet voivat myös muuttua suorituksen aikana, jolloin käytetään apuna tähän tarkoitettu laitteistoa (muistinhallintayksikköä).

Tietokoneen suorittimen käyttämään osoitteeseen viitataan tyypillisesti loogisena osoitteena ja muistinhallintayksikön käyttämää osoitetta kutsutaan fyysiseksi osoitteeksi. Käännösaikainen ja ja latausaikainen osoitteiden *sidonta* () tuottavat identtisiä loogisia ja fyysisiä osoitteita, mutta suorituksen aikaisessa sidonnassa ne eroavat. Suorituksen aikaisessa sidonnassa tuotettua loogista osoittetta kutsutaan virtuaaliosoitteeksi. Muistinhallintayksikkö muuntaa virtuaaliset osoitteet fyysisiksi osoitteiksi ajonaikaisesti.

Ohjelmat voivat käyttää ajonaikaisia kirjastoja, jolloin osa ohjelman toiminnoista linkitetään ohjelmaan latausvaiheessa. Käyttöjärjestelmä voi jakaa kerran ladatun kirjaston sen käyttäjien välillä, mutta kirjastosta voi olla useita versioita käytössä samaan aikaan.

Moniohjelmoinnin myötä tietokoneen muisti on jaettu useiden prosessien kesken. Tyypillisesti ohjelmoija ei voi tietää etukäteen mitä muita ohjelmia on samaan aikaan muistissa, sekä halutaan mahdollisuus vaihtaa suoritettavaa ohjelmaa muistista suorittimen käytön maksimoimiseksi. Ohjelma, joka on siirretty levylle voi olla tarpeen sijoittaa eri paikkaan muistissa kun se palautetaan suoritukseen. Ohjelman haarautumisen käsittely sisältää osoitteen seuraavaksi suoritettavalle käskylle ja suorittimen sekä käyttöjärjestelmän on ylläpidettävä ohjelman muistiviittauksille osoitteen muunnosta.

Prosessit on myös suojattava toisten ohjelmien tahattomilta tai tahallisilta yrityksiltä haitata ohjelman toimintaa. Lisäksi ohjelmat voivat laskea muistiviittaukset kuten sijainnin taulukossa ajonaikaisesti. Lisäksi jos useampi prosessi toimii yhdessä ja käsittelee samaa tietoa tuo voidaan haluta jakaa sitä käsittelevien prosessien kesken.

Useimmat nykyaikaiset järjestelmät käyttävät virtuaalimuistia, joka perustuu yhteen tai molempiin perustekniikoista, jotka ovat segmentointi ja sivutus. Myös muistin osiointia () on käytetty nyt vanhentuneissa järjestelmissä. Kiinteän ja dynaamisen osioinnin heikkouksien johdosta syntyi *kaverijärjestelmä* (), jossa varattava lohko jaetaan pienempiin mikäli tilaa ei ole riittävästi vapaana. Segmentointi jakaa muistin vaihtuvan kokoisiin lohkoihin, jolloin ohjelman ohjelmakoodi, pino ja keko sijoitetaan eri segmentteihin. 

Sivutuksessa muisti jaetaan kiinteän kokoisiin lohkoihin, joita kutsutaan sivuiksi. Kun on tarvetta käyttää enemmän muistia kuin tietokoneessa on fyysisesti voidaan osa muistisivuista *sivuttaa levylle*. Sivutus mahdollistaa sen, että prosessin käyttämän fyysisen muistiavaruuden ei tarvitse olla yhtenäinen (jatkuva).

## Keko
Keko on dynaamisesti hallittava muistialue, josta ohjelma varaa tarvitsemansa tilan tiedon käsittelyyn. Toisin kuin ajonaikaisen pinon käsittelyssä ohjelmoija voi itse hallita keosta varatun alueen elinkaaren ja voi luoda siihen tietorakenteen, jonka ohjelmoija palauttaa kutsujalle. Lisäksi ohjelmoija voi hallita varatun muistin määrää tarkemmin kuin pinolle, joka voi olla pieni.

## Dynaaminen muistinvaraus
Dynaaminen muistinvaraus () on muistinvarausmenetelmä, jossa tietokoneohjelma suorittaa ajon aikana muuttujan tai muistilohkon varauksen tietokoneen muistista. Dynaamista muistinvarausta käytetään, kun tarvittavan muistin määrää ei tiedetä etukäteen ohjelmaa kirjoitettaessa. Esimerkki tällaisesta tilanteesta on esimerkiksi kuvankäsittelyohjelma: ohjelmoija ei voi tietää etukäteen, minkä kokoisia kuvatiedostoja käyttäjä haluaa avata ohjelmalla.

Dynaamista muistinvarausta käytettäessä ohjelma ei voi tietää etukäteen, minkä keskusmuistin kohdan käyttöjärjestelmä sille antaa. Tämän takia dynaamisesti varattuja muistialueita käytetään epäsuorasti, yleensä osoittimen avulla.

Dynaamisesti varattu muisti varataan keosta ().
C-kielellä dynaaminen muistinvaraus toteutetaan `malloc(), calloc(), free()` ja `realloc()` -funktioilla. Ajonaikaisesta pinosta voi varata automaattisesti vapautettavaa muistia `alloca()`-funktiolla, mutta tämä voi aiheuttaa pinon ylivuotovirheen () mikäli riittävästi muistia ei ole saatavilla.

Dynaaminen muistinvaraus voi johtaa ohjelmointivirheisiin, kuten muistivuotoihin. Lisäksi varatun muistin vapautus voi viedä ennustamattoman paljon aikaa. Riskin vuoksi dynaamista muistinvarausta vältetään luotettavuutta vaativissa tai reaaliaikajärjestelmissä.
Ilmailun laatustandardi DO-178B (Software Considerations in Airborne Systems and Equipment Certification) kieltää dynaamisen muistinvarauksen käytön turvallisuuskriittisissä ilmailujärjestelmissä.

## Muistisuojaus
Muistisuojaus on muistinhallinnan ominaisuus, joka tarkoittaa laitteiston kykyä estää ohjelmaa käyttämästä toiselle ohjelmalle varattua muistialuetta paitsi tarkasti määritellyissä tilanteissa. Yritys käyttää muistia ilman pääsyoikeutta aiheuttaa keskeytyksen, jolloin käyttöjärjestelmä voi pysäyttää tai resetoida ongelman aiheuttajan. Suojauksen käsittelee mikropiiri, jota käyttöjärjestelmä ohjaa.
Avainpohjaista menetelmää voidaan käyttää vahvistamaan sivupohjaista suojausta.

## Katso myös
* Automaattinen roskienkeräys
* ASLR

## Lähteet
* Jaakkola, Matti: Muuttujien tilanvaraus 

### Viitteet

## Aiheesta muualla
* C++-ohjelmointi: Osa 7 - Viittaukset, osoittimet ja dynaaminen muisti