Uw computer heeft niet alleen RAM. Het heeft een rommelig, gefragmenteerd, voortdurend veranderend geheugenlandschap waarvan de CPU doet alsof het oneindig is. Dit is de realiteit van dynamische datastructuren die op moderne hardware draaien.
Een typisch werkstation beschikt tegenwoordig over 16 tot 64 megabytes fysiek RAM-geheugen. Maar laat je niet misleiden door die kleine aantallen. Via een techniek die virtueel geheugen wordt genoemd, wisselt het systeem gegevens uit tussen dat RAM-geheugen en de harde schijf. De CPU ziet een illusie. Het denkt dat het 200 tot 500 megabyte aan aaneengesloten ruimte heeft. De illusie werkt. De code wordt uitgevoerd. Maar wanneer het besturingssysteem in de harde schijf moet graven om een pagina geheugen op te halen, wordt alles langzamer. Je voelt het in de vertraging. Je voelt het aan het draaien van de ventilator. Ondanks de prestatiewinst is virtueel geheugen een goedkope manier om uw RAM-geheugen te “uitbreiden”. Het is een noodzakelijk compromis.
Laten we uitgaan van een schone lei. Een totale geheugenruimte van 50 megabytes. Niet meer. Niet minder. Dit is de begroting.
Het besturingssysteem is eigenaar van dit blok van 50 megabyte. Het verdeelt de taart. Niet gelijk. Nooit gelijk.
Ten eerste is er de code. De uitvoerbare instructies voor elke applicatie die momenteel wordt uitgevoerd, plus de OS-kernel zelf. Dit gedeelte is statisch. Het verandert niet terwijl het programma leeft. Vervolgens komen de globale variabelen. Dit zijn de gedeelde constanten en statusvlaggen die elk onderdeel van de applicatie kan aanraken. Ze blijven in het geheugen zitten vanaf het moment dat de app wordt gestart totdat deze sterft.
Dan is er de stapel.
De stapel is stijf. Het groeit en krimpt mee met functieaanroepen. Wanneer u een functie aanroept, worden de lokale variabelen en parameters ervan naar de stapel geduwd. Wanneer de functie terugkeert, worden ze verwijderd. De stapel onthoudt de callvolgorde. Het zorgt ervoor dat u terugkeert naar de juiste plaats. Maar er is een maximale omvang. Je kunt de stack niet halverwege de vlucht om meer geheugen vragen. Als je het probeert, loopt de stapel over. Het programma crasht.
Wanneer een programma is voltooid, wordt het door het besturingssysteem verwijderd. De code, de globalen, de stapelruimte: alles wordt schoongeveegd. Die herinnering wordt gerecycled. Het is klaar voor het volgende programma.
Maar hier is het probleem. Op elk gegeven moment kan ongeveer 50 procent van die 50 megabyte ruimte ongebruikt zijn. Waarom? Omdat de stapel alleen bevat wat momenteel wordt uitgevoerd. De code bevat alleen de instructies. De ongebruikte stukjes geheugen zijn verspreid. Het zijn gaten.
Het besturingssysteem neemt deze gaten en groepeert ze samen. Het noemt deze collectieve pool de hoop.
Dit is waar dynamische toewijzing plaatsvindt. De heap is de enige plek in het geheugen waar een programma om een exacte hoeveelheid ruimte kan vragen, precies wanneer het die nodig heeft. U declareert geen array van 1000 gehele getallen tijdens het compileren. Je weet niet of je 1000 of 100.000 nodig hebt. Wacht maar. Je voert de code uit. Je besluit dat je die ruimte nodig hebt. Dan noem je ‘malloc’.
malloc staat voor geheugentoewijzing. Hij pakt een blok van de hoop. Er wordt een aanwijzer geretourneerd. Jij gebruikt die aanwijzer. Als je klaar bent, bel je ‘gratis’. Het blok gaat terug het zwembad in.
Dit is het fundamentele verschil tussen statisch en dynamisch geheugen. De stapel gebeurt automatisch. Het is gebonden aan reikwijdte. De hoop is handmatig. Het is gebonden aan intentie.
Waarom is dit belangrijk voor jou? Omdat de meeste bugs in complexe software niet voortkomen uit slechte logica. Ze komen voort uit slecht geheugenbeheer. Als u toewijst vanuit de heap en vergeet deze vrij te maken, lekt er geheugen. De hoop krimpt. Uiteindelijk heeft het systeem geen ruimte meer. Programma’s lopen vast. Het besturingssysteem doodt processen. U verliest niet-opgeslagen werk.
Omgekeerd, als u te veel op de stapel probeert toe te wijzen, overschrijdt u de stapellimiet. Het programma stopt abrupt.
De hoop zorgt voor flexibiliteit. Het maakt datastructuren mogelijk die groeien. Gekoppelde lijsten. Bomen. Grafieken. Geen van deze kan tijdens het compileren met een vaste grootte worden gedefinieerd. Ze moeten ter plekke worden gebouwd. Ze moeten op de hoop leven.
Is de hoop perfect? Nee. Het fragmenteert. Terwijl je blokken van verschillende groottes toewijst en vrijmaakt, wordt de hoop een puzzel met ontbrekende stukjes. Het vinden van een aaneengesloten blok vrij geheugen kan traag worden. Dit is de reden waarom ‘malloc’ soms merkbaar veel tijd in beslag kan nemen. Het moet zoeken. Het moet samenvloeien. Het moet de chaos beheersen.
Maar zonder de hoop stort de moderne computer in.


























