Hovedminne

I datamaskiner er **hovedminne**, også kalt **arbeidsminne** eller **primærminne**, den delen av minnet i en datamaskin hvor prosesser ligger klare for kjøring av et program eller en prosess i maskinen. De lagrede dataene hentes fram i vilkårlig (engelsk: *random*) rekkefølge, derav det engelske navnet *random-access memory* (**RAM**). Andre navn er *arbeidslager*, *arbeidshukommelse*, *hovedhukommelse*, *primærhukommelse*, *primærlager*, *internhukommelse* eller *internminne*.

Hovedminnet står i motsetning til sekundærminne som ofte lagres på andre lagringsmedier (slik som magnetbånd, harddisk eller halvlederminne), og hvor (i motsetning til RAM) data bare kan aksesseres i forhåndsbestemt rekkefølge.

## Hovedminnets oppgaver
Et program må alltid legges i minnet før det kan kjøres. Alle data må legges i minnet før datamaskinen kan regne med dem eller manipulere dem, dessuten må alle inndata og utdata innom minnet.
 
Innholdet i RAM kan leses og skrives tilfeldig og uten noen bestemt rekkefølge, derav navnet, og går tapt når maskinen skrus av.

Datamaskiner har også en raskere type minne, kalt hurtigminne (cache). Under kjøring vil det hele tiden kopieres instruksjoner og data over fra hovedhukommelsen til hurtigminnet, da må ting innom der før de går videre til prosessoren.

Leser man minnet, henter man ut data uten å forandre dem. Ved skriving til minnet, vil data som ligger på de tilskrevne plassene i minnet gå tapt. Skriving til minnet kalles derfor en *destruktiv operasjon*.

## Adressering av minnet
Minnekapasitet måles typisk i megabyte eller gigabyte. Hver byte (enhet) i minnet får tildelt sin egen unike adresse, som regel sekvensielt, begynnende fra 0.

Maskinvare bruker ofte *absolutt adressering* av minnet. Da leser enheten en bestemt byte fra minnet, for eksempel byte 23&nbsp;425. Dette er den raskeste måten å lese av minnet på.

Når en ny prosess legges inn i minnet, legges den inn på et ledig sted som ikke kan forutsees av programutvikleren. En prosess vil ofte legges forskjellig sted hver gang den kjøres. Det blir derfor svært upraktisk å bruke absolutt adressering i slike tilfeller. Løsningen blir da å bruke *relativ adressering*. Med relativ adressering angis en minneplass som relativ i forhold til en basisadresse i minnet, og i løpet av kjøretiden kan da den absolutte minneadressen regnes ut på grunnlag av summen av basisadressen og den relative adressen.

## En oversikt over minneområdet til en prosess

En prosess får ved oppstart tildelt sitt eget minneområde. Dette området kan i hovedsak bare brukes av den enkelte prosessen, operativsystemet har sperrer mellom minneområdene som forhindrer at en prosess får lov til å skrive til andres minneområder.

En prosess sitt minneområde deles inn i fire hovedområder:

### Systemdatasegmentet
Dette segmentet ligger i området med de laveste minneadressene. Det inneholder blant annet pekere til de andre segmentene og til stacken, samt pid-en til prosessen.

### Kodesegmentet
I dette segmentet ligger all programkoden til programmet. Denne kopieres hit under oppstarten av programmet, og prosessen kan ikke skrive til dette segmentet under kjøring.

Dette segmentet kan deles av flere prosesser.

### Datasegmentet
Dette segmentet inneholder alle globale variable, både initierte og ikke-initierte. Dessuten inneholder segmentet den såkalte Heapen, et område programmereren kan bruke til å allokere minne dynamisk. Om tilgangen til ikke-globale variable skal kunne deles av flere funksjoner under kjøring, må disse legges her. Heapen vokser inn i den ledige minnedelen, mot høyere minneadresser.

### Stakken
Stakken (*stabelminnet*) inneholder alle lokale variable i en funksjon. Den inneholder også alle registertilstander.

Stakken vokser mot lavere minneadresser.

## Oppsett av minne
Minnet i en datamaskin er delt i flere områder. De laveste minneområdene er reservert for operativsystemet, og kan ikke brukes av brukerinitierte prosesser. 

Resten av minnet brukes av de forskjellige applikasjonene. Det finnes flere måter å fordele dette mellom de forskjellige prosessene.

### Partisjonering
Med *partisjonering* (partitioning) deles minneområdet inn i partisjoner, under oppstarten av datamaskinen. Disse partisjonene kan enten være like store med statisk størrelse og inndelt ved oppstart av datamaskinen, eller av dynamisk størrelse og inndelt fortløpende. I den grad moderne operativsystemer bruker partisjonering, brukes dynamisk partisjonering. Dette er fordi partisjoner av lik størrelse setter en maksimal øvre grense på størrelsen til programmer som kan flyttes over i minnet, og gjør at små prosesser bruker mye mer minne enn hva som egentlig er nødvendig. 

Med bruk av *dynamisk partisjonering* kan størrelsen på minnepartisjonene avgjøres før kjøring, og partisjonen kan fjernes igjen etter en prosess er ferdig. Det vil imidlertid være vanskelig for operativsystemkjernen å anslå den nødvendige størrelsen på en partisjon før programmet skal kjøre. Denne strategien har derfor den ulempen at den vil føre til fragmentering av minnet etterhvert som systemet kjører. Defragmentering av minnet vil da senere stjele tid og ressurser fra systemet, da dette er en kostbar prosedyre.

### Segmentering
Bruker man *segmentering* (segmentation) til å håndtere minneblokker innføres det en ekstra tabell over minnet i operativsystemet. Denne tabellen holder rede på minneblokkene, som da kan være av ulik størrelse. Denne størrelsen bestemmes av programmereren. 

Med segmentering blir problemet med fragmentering av minnet mye mindre enn med bruk av partisjonering. Ulempen er at den ekstra tabellen legger til en ekstra omregning for at man skal finne en minneadresse.

### Paging
Med bruk av *paging* deles minnet inn i flere minnerammer. En prosess vil så deles opp i flere *pages*, og disse vil kunne fordeles rundt i minnerammen. Siden de forskjellige pages til en prosess ikke trenger å ligge sekvensielt, vil man eliminere problemene med ekstern fragmentering som man har med bruk av partisjonering og segmentering. Det vil imidlertid være en liten intern fragmentering med bruk av paging, avhengig av størrelsen på rammene.

Som med segmentering krever paging fortløpende omregning av minneadresser under kjøring.

Det er også mulig å kombinere paging med fragmentering av minnet. 

### Virtuelt minne
Moderne operativsystemer som Microsoft Windows og Unix bruker paging i kombinasjon med *virtuelt minne* («tilsynelatende minne», også kalt *swapping*). Med virtuelt minne settes en seksjon av platelageret til side, og gis funksjonalitet som minne på tross av den store hastighetsforskjellen mellom «ekte» minne og platelagere.

Det virtuelle minnet får tildelt minneadresser akkurat som det ordinære minnet. En egen tabell holder rede på disse adressene og den samsvarende delen av platelageret. Om prosessoren (via hurtigminnet) ber om innholdet i en minneadresse som ligger i det virtuelle minnet, kastes lite brukt innhold i det egentlige minnet ut til fordel for de etterspurte dataene som ligger i det virtuelle minnet. Da dette er en svært dyr operasjon finnes det mange forskjellige algoritmer som prøver å gjøre dette på en best mulig måte. En typisk strategi vil være å kopiere over også nærliggende minneområder i tillegg til det som egentlig var etterspurt, da sjansen er stor for at også disse vil bli etterspurt i nær fremtid. Samtidig må også operativsystemet gjøre antagelser om hvilke data i minnet som vil bli minst etterspurt fremover, slik at man kan «kaste ut» disse fra minnet og dermed minimere sjansen for nye bytter mellom det egentlige minnet og det virtuelle minnet.

## Typer RAM
*Magnetkjerneminne (historisk)
*SIMM-RAM
*EDORAM
*SDRAM
*DDR SDRAM
*ECC-RAM
*SRAM
*DRAM
*SO DIMM
*RDRAM (Rambus)

## Se også
*ROM (Read-Only Memory), RAM-lignende minne som bare kan leses fra, og ikke skrives til.