La gestió de memòria a Linux
Introducció
La gestió de memòria és una part clau en l’eficiència d’un sistema operatiu, i en aquest post descobrirem com funciona a Linux.
Espai de memòria únic
En sistemes sense memòria virtual, on tenim un únic espai d’adreces compartit entre memòria i perifèrics, es presenten certs problemes:
-
Memòria no protegida
-
Els processos poden “aixafar-se” entre si
-
L’espai d’usuari pot interactuar amb memòria del kernel
A més, gestionar diferents processos és complex, ja que s’han de mantenir separats però cadascú ha de tenir les seves zones de memòria ben definides.
Aquí és on entra en joc la memòria virtual.
Memòria virtual
És una solució al problema de l’espai de memòria únic: un sistema que utilitza mapatge d’adreces:
-
Mapeja adreces virtuals a adreces de RAM física
-
Mapeja adreces virtuals a dispositius de hardware
Gràcies a la memòria virtual, cada procés té un espai d’adreces separat de la resta. Això ens ofereix molts avantatges com:
-
Tenir mapatges diferents per cada procés
-
Els processos són invisibles entre si
-
La memòria del kernel també és invisible per als processos en espai d’usuari
-
-
La memòria es pot moure
-
La memòria pot canviar a disc (swap)
-
La mateixa àrea de memòria pot estar mapejada a diferents processos alhora (memòria compartida)
-
Les regions de memòria poden tenir permisos d’accés
Llavors tenim 2 espais d’adreces:
-
Adreces físiques
Utilitzades per hardware
-
Adreces virtuals
Utilitzades pel software
El mapeig d’adreces: la MMU
La MMU (Memory Management Unit) és un component de hardware entre la CPU i la memòria que s’encarrega de traduir direccions virtuals a físiques, a més d’aplicar permisos d’accés i generar page faults quan la traducció no es vàlida segons les page tables.
La MMU opera sobre pages.
Pages i page frames
Abans de seguir és important conèixer el que són les pages i page frames:
-
Pages
Unitat mínima de memòria (normalment 4KB)
-
Page frame
Bloc real de memòria física, alineat i de mida de la page
El kernel té una estructura struct page per cada page frame físic, que conté flags (atributs) i un comptador de referències (quants processos tenen la page en ús).
TLB
La MMU utilitza una caché especial: el TLB (Translation Lookaside Buffer). Aquest TLB conté mapatges recents i permisos, és extremadament ràpid però també és limitat.
El procés per accedir a memòria és el següent:
-
La CPU accedeix a una adreça virtual
-
La MMU consulta el TLB
-
Si la adreça virtual està al TLB, hi accedeix
-
Si no hi és, la MMU la intenta buscar a les page tables
-
Si no es pot accedir, genera una page fault
Una page fault és una excepció que es dona quan l’adreça no està mapejada, no hi ha prou permisos, la pàgina està swappejada o la pàgina encara no ha estat assignada.
No tots són errors, és part del funcionament normal del sistema.
Page tables
Com hem comentat, el TLB és limitat, i això és un problema, ja que el kernel ha de conèixer tots els mapatges del sistema. Aquí és on entren en joc les page tables.
Al accedir a una adreça que no està al TLB, la MMU la busca per ls page tables i, si no hi pot accedir, llença una page fault i anirà a bucar-la a les page tables.
En x86_64, Linux té una jerarquia de 4 nivells (5 en sistemes més moderns) de page tables. Quan es genera una page fault, primer anirà al registre CR3 (conté l’adreça física del PGD del procés actual), i des d’allà:
PGD -> PUD -> PMD -> PTE
On aquests noms són els noms de les diferents page tables. Són una mena d’índexos on cada cop s’afina més la cerca.
Huge pages
També tenim el concepte de les huge pages, que són pàgines més grans que estalvien un o dos nivells de page tables, fent el procés més eficient.
Swapping
El swapping és un procés que ens permet utilitzar memòria de disc com si fos RAM (amb certs matisos).
Quan falta memòria RAM:
-
El kernel copia un page frame a disc
-
La entrada del TLB s’invalida
-
El mapatge s’elimina de la page table
-
Reutilitza el frame físic que ha quedat lliure a RAM
I quan volem tornar a accedir a la memòria swapejada:
-
Page fault
-
Es bloqueja el procés
-
La pàgina en swap torna a RAM
-
Es remapeja
-
El procés continua
Tot i que la adreça física que tingui ara el page frame pugui haver canviat, la MMU s’encarregarà que la adreça virtual sigui la mateixa.
Lazy allocation
Quan un procés demana memòria, el kernel no la assigna immediatament, només crea el mapatge virtual i, quan calgui utilitzar la memòria, ja la assignarà.
Aquest procés s’anomena lazy allocation i redueix molt el consum de RAM i millora el rendiment del sistema.
Per aplicacions sensibles al temps d’operació, es poden pre-faultar pàgines amb mlock() i mlockall().
Conclusió
La gestió de memòria és un procés ben executat que dona a aquest sistema operatiu molt rendiment, escalabilitat, flexibilitat i seguretat.
Fins aquí el post d’avui, si tens alguna suggerència que podria mirar d’implementar per millorar el meu entorn, servidor o el que sigui, o simplement t’ha agradat el post, pots deixar un comentari i compartir. Bones festes i ens veiem al següent!



