Allocateur mémoire en Java TP4 et TP5 : Pratique

Transcription

Allocateur mémoire en Java TP4 et TP5 : Pratique
Allocateur mémoire en Java
TP4 et TP5 : Pratique
V.Marangozova-Martin, Ludovic Démontes
1
L’allocation de mémoire
L’utilisation de la mémoire est indispensable dans toute exécution de programme. Quand un programme est lancé, afin de créer le processus qui a son
tour manipulera des données, le système alloue une zone mémoire. Quand le
processus termine, sa mémoire est libérée et peut être utilisée (allouée) par
d’autres processus.
De la même manière, quand un programmeur a besoin d’initialiser une donnée pendant l’exécution de son programme, il doit d’abord s’assurer que la variable va pouvoir être placée en mémoire 1 . Pour cela, il doit demander (allouer)
de la mémoire pour sa variable. Une fois le travail avec la variable terminé, le
programmeur doit libérer la mémoire afin de la rendre disponible pour d’autres
variables.
En C ou C++ les opérations d’allocation/libération sont explicites dans le
programme (malloc/free). En Java, l’allocation/libération est gérée implicitement par la JVM. En effet, lors de la création d’un nouvel objet (new), la
JVM alloue la mémoire nécessaire. La libération de la mémoire est faite par le
ramasseur de miettes (garbage collector ) qui vérifie si un objet est encore utilisé
et si non, récupère sa mémoire.
Un allocateur mémoire est le gestionnaire qui a accès à la mémoire et qui
tient compte des zones de mémoire libres et des zones mémoire occupées. C’est
ce gestionnaire qui fournit les opérations d’allocation/libération de mémoire qui
sont utilisées par le système/l’utilisateur.
2
Objectif du TP
Dans ce TP, vous avez pour objectif d’implémenter un allocateur simple
qui gère la mémoire physique dont la taille est définie de manière statique.
1 Il
s’agit surtout des cas où on manipule des pointeurs.
1
Miage3, 2009-2010
2
L’allocateur devra :
– connaître l’état de la mémoire i.e les zones libres et les zones occupées ;
– allouer des zones de mémoire lorsque le système ou l’utilisateur les demande ;
– libérer des zones de mémoire utilisées lorsque le système ou l’utilisateur
n’en a plus besoin.
3
Réalisation
L’allocateur sera implémenté par une classe Allocateur qui aura des attributs représentant la mémoire physique, ainsi que deux méthodes alloc et free.
Cette classe devra être réalisée en suivant les étapes décrites ci-dessous.
3.1
Représentation de la mémoire
La mémoire physique sera représentée dans la classe Allocateur par un
attribut de type Memoire. La classe Memoire contiendra deux choses : les structures de données qui permettent de gérer la mémoire, ainsi que les structures
qui représentent l’espace mémoire utilisable.
class Memoire {
public static int SIZE = ...;
// taille memoire en octets
private BitSet bitset ;
// structure de gestion
private StringBuffer mainmemory ; // la memoire disponible
...
// methodes
}
L’attribut SIZE est à fixer à votre convenance, il représentera la taille en
octets de la mémoire utilisable.
L’attribut bitset représentera l’état de la mémoire. Cet attribut sera un
vecteur de bits, chaque bit étant rattaché à une zone mémoire différente. Si
on décide de découper la mémoire en zones de 10KO, alors bitset contiendra
SIZE/10KO bits. Un bit positionné à 1 indiquera que la zone est occupée
(allouée), alors qu’un bit à 0 indiquera que la zone est libre2 .
L’attribut mainmemory, un "tableau" de caractères, représente la mémoire
allouable. Un caractère étant encodé sur un octet, la taille de la mémoire correspond au nombre de caractères présents dans mainmemory. Il faut veiller à ce
que cette taille soit cohérente avec SIZE.
2 Ceci
devrait vous rappeler la pagination.
Miage3, 2009-2010
3
Question 1 : Implémentation de la classe Memoire Créer la classe Memoire
et écrire son constructeur afin d’initialiser les attributs de manière cohérente.
Quelle doit être la taille du bitset ? Comment doit-il être initialisé ? Quelle est
la taille de mainmemory ?
Si vous faites correspondre 1 bit de la bitset à 1 octet en mémoire, quelle
sera la taille de la bitset ? Et si vous faites correspondre 1 bit à une zone de 10
octets, de 20 octets, de 1KO ? Que se passe-t-il au niveau fragmentation ?
3.2
Implémentation des méthodes alloc et free
Nous allons implémenter les stratégies d’allocation en zones contiguës.
La méthode alloc prendra en paramètre le nombre d’octets demandés. Elle
retournera comme résultat un identifiant de la zone allouée. Cet identifiant sera
utilisé plus tard pour la libération de la zone. SI l’allocation échoue, alloc
retournera −1.
La méthode free prendra deux paramètres afin de libérer une zone mémoire :
l’identifiant d’une zone allouée et sa taille. Elle retournera 0 en cas de réussite
et −1 sinon.
class Allocateur {
private Memoire memory ;
...
// methodes
public Allocateur () { /* ... TO DO ... */ }
public int alloc ( int nbOctets ) { /* ... TO DO ... */ }
public int free ( int idZone , int nbOctets ) { /* ... TO DO ... */ }
}
Question 2 Que doit faire le constructeur de la classe Allocateur ? Ecrire ce
constructeur.
Question 3 Imaginons que la mémoire est vide. Comment doit être traitée
la demande alloc(10) ? Quelle partie de la mémoire sera occupée ? Que se
passera-t-il avec le bitset ?
Question 4 Imaginons que la mémoire a été utilisée pendant un certains
temps et a déjà "subi" plusieurs allocations et libérations. Elle sera typiquement
composé de zones libres et de zones occupées qui s’intercalent. Nous avons vu en
Miage3, 2009-2010
4
cours que pour allouer une nouvelle zone il existe plusieurs stratégies. Quelles
sont les trois stratégies existantes ?
Question 5 Comment doit être traitée la demande alloc(10) dans le cas
général (mémoire non vide) avec une stratégie first fit ? Comment trouverezvous la zone adéquate ?
Ecrire la méthode alloc.
Question 6 Pourquoi la méthode free doit prendre en paramètre la taille de
la zone ? Que se passerait-il si ce paramètre est omis ?
Question 7 Comment doit être traitée la demande free(10, 25) ? Que se
passe-t-il au niveau du bitset ?
Ecrire la méthode free.
4
Et la synchro dans tout cela ?...
Vous avez écrit votre allocateur et il marche très bien dans le cas d’un programme qui fait des appels à alloc et free. Que se passe-t-il, par contre, si
plusieurs threads appellent simultanément ces méthodes ? Comment corriger le
problème ?
5
Un peu de reflexion...
Question 8 Nous avons présenté la mémoire par la classe Memoire. D’après
vous, les données permettant la gestion de la mémoire (SIZE et bitset) doiventils être gardés en mémoire ? EN d’autres termes, les structures pour la gestion
de la mémoire doivent-ils être stockées en mémoire ? Que cela implique-t-il en
ce qui concerne la taille de la mémoire disponible pour les programmes ?
Question 9 Qui est sensé manipuler les structures de gestion de la mémoire ?
Le système ou un programme utilisateur ?

Documents pareils