SSD:llä tilanne voi toki olla vähän parempi. HDD:llä muistin loppuminen saa koneen usein niin hitaaksi, että pakotettu uudelleenkäynnistys on ainoa käytännöllinen vaihtoehto.
Jos ohjelmien ei annettaisi varata enempää muistia kuin koneessa on oikeasti vapaana, ei muistin loppumisia sattuisi niin helposti:
- Prosessi yrittää varata muistia enemmän kuin on mahdollista --> varaus epäonnistuu, siitä eteenpäin toiminta on prosessin vastuulla
- Prosessi yrittää käyttää muuta kuin varaamaansa muistia --> prosessi suljetaan pakolla (kuten yleensä nykyäänkin)
Käynnissä olevien prosessien tappaminen tulisi eteen vasta sitten, jos käyttöjärjestelmälle tulisi pakottava tarve varata lisää muistia eikä sitä olisi saatavilla tarpeeksi.
Tämä olisi
todella epätehokasta muistienhallintaa ja ohjelmat kaatuilisivat tai bugailisivat jatkuvasti muistin loppumiseen ja kone toimisi todella hitaasti.
Se, että koodissa on malloc() tai new() ei ole sama asia kuin se, että prosessi pyytää muistia käyttikseltä.
Ja se, että prosessi pyytää muistia käyttikseltä ei myöskään tarkoita sitä, että se prosessi saa sen pyytämänsä muistin
täysin omakseen.
Kun koodissa suoritetaan se malloc() tai new, sen tekee tyypillisesti standardikirjaston malloc()-toteutus joka ajetaan ihan siellä user-tilassa, se ei yleensä mene käyttikselle asti.
Käyttikseltä saa muistia varattua minimissään virtuaalimuistisivun kokoisissa palasissa(*), ja käyttiskutsut on hitaita. Käyttikseltä pyydetään muistia harvemmin, ja paljon isommissa paloissa.
Käytännössä kuvio toimii siten, että ohjelmaa käynnistettäessä siellä saattaa olla jo valmiina saatuna käyttikseltä virtuaaliosoiteavaruutta tulevia malloc/new-kutsuja varten. Ja esimmäiset n malloc/new-kutsua käyttävät näitä osoitteita, eivätkä varaa käyttikseltä mitään.
Sitten kun tämä loppuu, varataan sitä käyttikseltä isompi pala kerrallaan.
Ja kun ohjelma pyytää käyttiseltä muistia, käyttis ei varaa sille oikeaa omaa fyysistä muistia. Kaikki se muisti, mikä prosessille palautetaan, saattaa olla viittausta samaan pelkkää nollaa sisältävään 4 kiB viruaalimuistisivuun, joka on jaettu ziljoonan muun ohjelman kanssa, ja se annetaan ohjelmalle read-only-moodissa.
Tällä tempulla säästetään huomattavasti muistia, koska tyypillisesti ohjelmat pyytävät paljon enemmän muistia kuin mitä oikeasti käyttävät.
Kun softa sitten myöhemmin yrittää kirjoittaa johonkin osaan tätä pyytämäänsä muistia, lentää poikkeus muistin laittomasta käytöstä. Käyttis toteaa että jaahas, nyt se sitten kirjoittaa sivuun jonka se joskus pyysi, tämä on ok, ja
vasta tässä vaiheessa varaa softalle uuden ikioman fyysisen muistisivun. Softan virtuaalimuistin mäppäys päivitetään siten, että tämä virtuaaliosoite mihin kirjoitettiin osoittaa nyt tähän uuteen sivuun, ja softalle annetaan siihen sivuun kirjoitusoikeus. Tämän jälkeen palataan softaan ja softan suoritus jatkuu suorittamalla kirjoituskäsky uudestaan.
Kaikki se muu muisti mitä samalla kertaa varattiin pysyy kuitenkin edelleen yhteisenä osoittamassa nollasivuun. Softa siis todellisuudessa usein kuluttaa systeemiltä todella paljon vähemmän muistia kuin mitä se on käyttikseltä pyytänyt.
Se, että se softa kaadettaisiin vain koska sen standardikirjaston malloc-toteutus on optimoitu siten, että se pyytää käyttikseltä ison poolin muistia kerrallaan olisi vaan todella typerää. Ja se, että malloc/new-toteutus pyytäisi aina käyttikseltä pienimmän mahdollisen määrän muistia (varauksen koko pyöristetynä ylöspäin virtuaalimuistin sivukokoon) tarkoittaisi sitä, että malloc/new hidastuisi selvästi.
Käyttis saattaa kuitenkin tehdä sen, että varautuakseen pahimpaan se pitää kirjaa siitä, paljonko kaikki softat yhteensä ovat muistia pyytäneet, eikä anna tämän kasvaa suuremmaksi kuin mikä on swapfileen maksimikoko + fyysisen muistiin koko, jolloin se ei voi koskaan joutua tilanteeseen, että se ei pysty "lunastamaan lupaustaan" aiemmin tehdystä muistinvarauksesta. Mutta kun softat eivät kirjoita läheskään kaikkeen pyytämästään muistista, sitä ei usein koskaan tarvi heittää edes swapfileeseen vaikka softat yhdessä olisivat varanneet muistia jonkin verran enemmän kuin mitä fyysistä muistia koneessa on.
Lisäksi kuviota monimutkaistaa paljon vielä esim. jaetut binäärit (ohjelmien omat binäärit sekä kirjastot). Nämä jaetaan hyvin tehokkaasti eri prosessien kesken, ja niitä voidaan ladata levyltä laiskasti.
Ja muistia voidaan käyttää myös levyvälimuistina. Tilanteessa jossa ohjelmat käyttävät muistia esim. n. 95-100% fyysisen muistin kapasiteetista, systeemin suorituskyky on keskimäärin paljon parempi kun joku 5-10% tästä heitetään swappiin ja 10% muistista käytetään levyvälimuistina, kuin että levyvälimuistille ei jää käytännössä ollenkaan muistia, ja joka ikinen hyvinkin pieni ja samaan paikkaan tehtävä toistuva levyaccessi joutuu aina menemään levylle asti.
Nykyaikaisella moniajokäyttiksellä on siis täysin normaalia, että softat "käyttävät" muistia yhteensä todella paljon enemmän kuin mitä koneessa on fyysistä muistia, ja silti swapissa ei välttämättä ole (juuri) mitään.
(*) Joillain käyttiksillä tämä saattaa olla muutaman sivun yhdistetty isompi blokki eikä yksi sivu, macos X(Sierrassa) kuitenkin ainakin tasan yksi sivu.