Gestion de la mémoire
02/04/2006
 Christian CALECA 
Liste des cours

Lorsque l'on travaille sur des processeurs simples, des micro contrôleurs, des PIC, on gère la mémoire de façon primaire. Autrement dit, lorsque le programmeur écrit une application, il gère lui-même les adresses utilisées en RAM par son code et par les les données manipulées par ce code.

Sur une architecture avancée de type Intel, par exemple (mais aussi PowerPC ou autre), la gestion de la mémoire est dite "virtuelle". Le programmeur travaille avec des adresses logiques, théoriques, qui n'ont aucune relation directe avec les adresses physiques, celles où la RAM est implémentée. Comme il faut bien tout de même qu'au bout du compte le programme s'appuie sur des adresses physiques, un mécanisme de traduction d'adresse est mis en place.

Le mécanisme de traduction d'adresses sur plate-forme Intel est extraordinairement complexe, aussi l'exposé qui suit s'appliquera d'avantage à démontrer la philosophie que son fonctionnement détaillé.

Pourquoi une mémoire "virtuelle" ?

Position aléatoire du code et des données en mémoire

Sur un système multi tâches, chaque application doit disposer d'un espace RAM personnel. A priori, le programmeur de l'application n'a aucun moyen de connaitre les adresses physiques en relation avec son code, c'est l'OS qui doit décider, en fonction des disponibilités en RAM du moment. Une méthode "simple" consiste en l'écriture de programmes "relogeables". Ce sont des programmes dans lesquels il n'est fait référence qu'à des adresses relatives (des sauts relatifs et jamais des JUMP à des adresses explicites). Cette méthode est bien trop contraignante pour de grosses applications, il est donc nécessaire de mettre en place un système qui soit transparent pour le programmeur, d'où l'idée d'employer des adresses virtuelles.

Espace de RAM disponible, variable d'une machine à l'autre

Nous savons tous qu'un PC peut être équipé de plus ou moins de RAM, selon les besoins. Habituellement, avec un système comme Windows XP et à l'heure où ces lignes sont écrites, 256 Mo de RAM sont un minimum et 512 Mo une moyenne.

Las processeurs Intel de type Pentium disposent d'un bus d'adresses de 32 bits, donc 232 adresses possibles, ce qui fait 4 Go de RAM adressable.

Le but à atteindre est de permettre aux programmeurs de concevoir leur application comme si 4 Go de RAM étaient disponible, même s'il y en a beaucoup moins en réalité. Le mécanisme de "swap" (fichier d'échange sur disque) permet d'atteindre cet objectif. Bien entendu, ce mécanisme est très coûteux en terme de performances et le programmeur aura toujours intérêt à être le plus économe possible en RAM.

Violation d'accès

Lorsque l'on construit un OS sérieux, l'une des priorités est d'empêcher à tout prix qu'une application puisse s'étaler sur un espace de RAM utilisé par une autre application. Chaque application doit travailler dans un espace qui lui est propre, sauf dans des cas bien précis où deux applications devraient pouvoir s'échanger des données. Là encore, le système de gestion de mémoire virtuelle va offrir des facilités pour gérer ces situations.

La MMU

Principe très schématique

La fonction qui a pour rôle de traduire les adresses logiques en adresses physiques s'appelle la MMU (Master Memory Unit). Cette fonction, dans les Pentiums est implémentée dans le boîtier du processeur.

principe

Toutes les adresses manipulées par des programmes sont des adresses virtuelles (logiques).

Avant d'être appliquées au bus de données, elles passent par la MMU qui les traduit en adresses physiques, au moyen de tables de conversion, qui sont maintenues par le système d'exploitation.

adresses Imaginons que, sur notre machine, deux applications A et B tournent "en même temps".

Elles n'ont pas besoin de savoir qu'elles sont plusieurs, chacune fonctionne pour son compte, c'est pourquoi certaines adresses logiques peuvent correspondre à l'une comme à l'autre.

Cependant, grâce aux tables de conversions d'adresses, les deux applications occuperont physiquement des zones de RAM distinctes.

adresses Imaginons maintenant que l'utilisateur démarre une troisième application C.

Elle aussi, toujours pour les mêmes raisons, peut utiliser des adresses logiques déjà employées par A ou B.

Le système doit mettre à jour les tables de translation d'adresses, mais il n'y a plus de place disponible en RAM physique.

adresses Le système va donc faire de la place, en déplaçant par exemple, le contenu de la RAM utilisée par l'application A vers le fichier d'échange sur disque dur.

Cette place en RAM est maintenant disponible pour l'application C.

Bien entendu, lorsque ce sera au tour de A de reprendre le travail, il faudra que l'OS restitue la zone de RAM disponible pour A (au même endroit ou ailleurs, ça n'a aucune importance, du moment que les tables de translation sont maintenues à jour).

Tout ceci reste très schématique, encore une fois. Dans la réalité, les choses se passent de façon un tout petit peu plus compliquée, mais le principe général est bien celui qui a été exposé.

Le "swap"

Le "swap" (échange de zones de données entre la mémoire vive et la mémoire de masse), intervient donc principalement lorsque la place vient à manquer en mémoire vive. La procédure est bien entendu assez longue et pénalise lourdement les performances.

Il est également possible d'exploiter une variante du swap, dans le cas de librairies dynamiques (les dll sous Windows, ou leur équivalent sous d'autres systèmes). Elles contiennent des "sous programmes" que les applications peuvent appeler si besoin est. Un mécanisme analogue à celui qui a été vu permet de les charger en RAM en cas de besoin.

Les exceptions de la MMU

Une exception est une sorte d'interruption. Dans le cas de la MMU, une exception sera levée chaque fois qu'une traduction d'adresse logique ne pourra donner une adresse physique, et sera traitée par le système d'exploitation. Le traitement variera en fonction de la nature de l'exception.

Plusieurs cas peuvent se présenter, mais qui se ramènent plus ou moins aux deux cas suivants :

N'oublions pas que l'OS lui même n'est qu'une application informatique. Certes un peu particulière. L'OS utilise donc lui aussi ce mécanisme d'adresses virtuelles, à partir d'un certain niveau d'avancement lors de son chargement, et durant toute la durée de la session (qui peut durer plusieurs années sur un serveur).

Lorsqu'une exception se produit sur une application de l'espace utilisateur, il n'y a généralement pas de problèmes, l'OS peut détruire cette application et poursuivre son travail.

Lorsqu'une exception se produit sur l'OS lui-même, soit elle fait appel au swap, auquel cas, il n'y a généralement pas de problèmes non plus, soit il faut détruire l'application, c'est à dire l'OS lui-même. Sur des systèmes comme Windows XP, ça se termine par un "reboot" ou un écran bleu, sur un système comme GNU/Linux, ça se termine par un message de type "kernel panic". Le système s'arrête, n'est plus opérationnel et il faut effectuer un "reset".