Gestion d’un tas
Systèmes d’exploitation
1
Problématique
2
Exemple
Tpoint* alloue_point (double x, double y, double z) {
Tpoint* p = malloc(sizeof(Tpoint));
p->x = x; p->y = y; p->z = z;
return p;
}
void libere_point (Tpoint* p) {
free(p)
}
3
Rappels: allocation statique
- s’applique aux variables locales
- stockage dans la pile (en anglais stack)
- allocation en entrant dans la fonction/procédure
- libération en sortant de la fonction/procédure
- gérée automatiquement par le compilateur
4
Rappels: allocation dynamique
- stockage dans le tas (en anglais heap)
- allocation/libération à la demande du programmeur
5
Besoins
Besoins: gérer l’occupation d’une plage de mémoire (éventuellement
extensible)
- réserver (allouer) des zones d’une taille spécifiée (
malloc
)
- libérer une zone préalablement réservée (
free
)
Critères:
- rapidité des opérations d’allocation et de libération
- surcoût en mémoire
- gaspillage (mémoire inutilisée sans raison)
6
Remarques
- Géré par les bibliothèques standards (
malloc/free
),
- voire par le langage lui même (
new/delete
),
- parfois de manière implicite (ramasse-miettes).
→ notion étendue de système d’exploitation.
7
Méthodes
8
Carte de bits
- le tas est subdivisé en blocs de taille fixe
- on établit une carte: un tableau de bits dont chaque bit représente l’état (libre/alloué) d’un bloc
map: 11000111 11000000 00111000 01111110
limits: 01000000 01000000 00001000 00100010
9
Avantages
10
Inconvénients
- allocation coûteuse en temps (recherche d’espace libre)
- fragmentation interne: certains blocs marqués comme occupés ne sont pas totalement utilisés
→ Peu utilisé en pratique
11
Liste chaînée
On représente l’état de la mémoire par une liste chaînée dont chaque maillon représente une zone (adresse, taille), son état (alloué ou libre) et pointe vers le maillon représentant la zone suivante.
12
Évaluation
- La durée des opérations et le surcoût en mémoire dépendent du nombre de zones alouées, et non de la taille du tas.
- Pas de fragmentation interne.
- Permet de gérer des zones allouées contigües.
- L’allocation et la libération sont encore relativement coûteuses (recherche dans la liste, y compris pour la libération).
13
Allocation
14
Libération
15
Choix d’une zone libre
Lors d’une allocation mémoire, si plusieurs zones libres de taille suffisante sont disponibles, laquelle choisir?
- Premier trouvé (first fit) : méthode la plus simple et la plus rapide
- Meilleur trouvé (best fit) : cherche la zone libre la plus petite,
c.à.d. la plus proche de la taille recherchée.
- Pire trouvé (worse fit) : cherche la zone libre la plus grande.
Avantages ? Inconvénients ?
16
Variante 1
17
Variante 1 (suite)
18
Variante 2
19
Variante 2 (suite)
20
Méthode Buddy
Principe
Méthode basée sur le principe dichotomique, permettant de diviser la taille du tas par des puissances de 2.
Inconvénients
- fragmentation interne (contrainte sur la taille des zones)
- fragmentation externe
Avantages
- efficace en temps (logarithmique par rapport à la taille de la mémoire)
21
Fonctionnement
- À chaque taille de zone correspond une liste chaînée.
- Allocation : au besoin, on divise par deux une zone libre, jusqu’à atteindre la taille (la plus proche de celle) à allouer.
- Libération : on fusionne deux zones libres si elles sont buddy (« potes ») c.à.d. issue de la division d’un même « père ».
22
Exemple
23
Application
Linux utilise la méthode Buddy pour l’allocation des pages.
→ La fragmentation (interne ou externe) n’est plus un problème puisque
- les pages ont toutes la même taille,
- elles n’ont pas besoin impérativement d’être contigües.
24
Méthode Slab
- Limitation : toutes les zones à allouer sont de la même taille (structures d’un type particulier)
- Principe : on réserve à l’avance un grand tableau (slab, ou « dalle »).
- On conserve
- la taille du tableau,
- une liste chaînée des cases libres.
- Allocation et libération en temps constant.
25
Illustration
NB:
- aucune référence explicite aux zone allouées.
- le dernier maillon de la liste désigne tout le reste du tableau.
26
Optimisation
On peut recycler les cases libres du tableaux elles même pour stocker
- l’entête du tableau,
- la liste chaînée,
→ surcoût mémoire minime.
27
Applications
- Linux utilise la méthode Slab pour l’allocation de ses structures internes (PCB, fichiers ouverts, i-nodes…).
- Chaque tableau occupe un nombre entier de pages.
- Pour chaque type de structure, Linux gère en fait une liste de tableaux (buffer) et y ajoute des tableaux au besoin.
28
Applications (2)
29
Extension: ramasse-miettes
30
Ramasse-miettes
Problème
- La gestion dynamique est une tâche fastidieuse et une source d’erreur (« fuites mémoires ») pour les programmeurs.
- Ceux-ci utilisent par ailleurs des outils informatiques pour les détecter et les corriger.
- Ne pourrait-on pas laisser l’ordinateur gérer la libération de mémoire tout seul?
Mise en œuvre
La plupart des langages modernes (Java, Javascript, PHP, Python, Ruby…) intègrent un mécanisme de ramasse-miettes (garbage collector).
31
Compteur de références
- Chaque objet possède un compteur de références indiquant combien de liens pointent vers lui.
- Chaque qu’on crée ou que l’on brise un lien vers un objet, son compteur de références est mis à jour.
- Lorsque son compteur de références atteint 0, l’objet est libéré, et ses liens son brisés.
32
Exemple
33
Références cycliques
Le comptage des références n’est pas suffisant.
→ nécessité de trouver un compromis entre l’économie de mémoire et le temps de clacul.
34