Module Gc
Le module Gc permet d'obtenir des statistiques sur le tas
et fournit un contrôle sur son évolution ainsi que sur le
déclenchement des différents GC. Deux types enregistrements concrets
sont définis : stat et control. Les champs du
type control sont modifiables. Ils permettent d'influer sur
le comportement du GC. Les champs du type stat ne le sont
pas. Ils reflètent simplement l'état du tas à un instant donné.
Les champs d'un enregistrement stat contiennent
principalement des compteurs indiquant :
-
nombres de GC : minor_collections,
major_collections et compactions
- nombre de mots alloués et transférés depuis le début
d'exécution du programme : minor_words,
promoted_words, major_words
Les champs d'un enregistrement control sont :
-
minor_heap_size qui définit la taille de la zone
dévolue à la jeune génération ;
- major_heap_increment qui définit l'incrément
appliqué à l'accroissement de la zone de l'ancienne
génération ;
- space_overhead qui définit le pourcentage de
mémoire utilisé au delà duquel un GC majeur est déclenché
(la valeur par défaut est 42) ;
- max_overhead qui définit le rapport entre
mémoire libre et occupé à partir duquel on déclenche la
compaction. La valeur 0 provoque une compaction systématique
après chaque GC majeur, la valeur maximale 1000000 inhibe la
compaction ;
- verbose est un paramètre entier gouvernant
l'émission d'une trace de l'activité du GC.
Les fonctions manipulant les types stat et control
sont données à la figure 9.13.
stat |
unit -> stat |
print_stat |
out_channel -> unit |
get |
unit ® control |
set |
control -> unit |
Figure 9.13 : fonctions de contrôle et de statistiques de tas
Les fonction suivantes de type unit -> unit permettent de
forcer l'exécution d'un nombre d'étapes plus ou moins grand du GC
d'Objective CAML : minor (étape 1), major (étapes 1
et 2), full_major (étapes 1,2 et 3) et
compact (étapes 1,2,3 et 4).
Exemples
Voici ce qu'indique l'appel de GC.stat :
# Gc.stat();;
- : Gc.stat =
{Gc.minor_words=5828243; Gc.promoted_words=509102; Gc.major_words=1002421;
Gc.minor_collections=184; Gc.major_collections=9; Gc.heap_words=579584;
Gc.heap_chunks=8; Gc.live_words=137371; Gc.live_blocks=28552;
Gc.free_words=199502; Gc.free_blocks=1690; Gc.largest_free=72704;
Gc.fragments=89; Gc.compactions=0}
On remarque le nombre d'exécutions de chaque phase : GC mineur, GC
majeur, compaction, ainsi que le nombre de mots traités par les
différents espaces mémoire. L'appel de compact force les
quatre étapes du GC. Les informations sur le tas sont effectivement
modifiées (voir appel de Gc.stat).
# Gc.compact();;
- : unit = ()
# Gc.stat();;
- : Gc.stat =
{Gc.minor_words=5834712; Gc.promoted_words=509935; Gc.major_words=1003254;
Gc.minor_collections=185; Gc.major_collections=11; Gc.heap_words=344064;
Gc.heap_chunks=5; Gc.live_words=223345; Gc.live_blocks=57824;
Gc.free_words=120718; Gc.free_blocks=2; Gc.largest_free=90112;
Gc.fragments=1; Gc.compactions=1}
Les champs GC.minor_collections et compactions sont
incrémentés de 1, alors que le champ Gc.major_collections
est augmenté de 2. Tous les champs du type GC.control
sont modifiables. Pour qu'ils puissent être pris en compte, on utilisera la
fonction Gc.set qui prend une valeur de type control
et modifie le comportement du GC.
Par exemple, le champ verbose peut prendre des valeurs de 0
à 127 activant 7 indicateurs différents.
# c.
Gc.verbose
<-
3
1
;;
Characters 1-2:
This expression has type int * int but is here used with type Gc.control
# Gc.set
c;;
Characters 7-8:
This expression has type int * int but is here used with type Gc.control
# Gc.compact();;
- : unit = ()
Ce qui affichera :
<>Starting new major GC cycle
allocated_words = 329
extra_heap_memory = 0u
amount of work to do = 3285u
Marking 1274 words
!Starting new major GC cycle
Compacting heap...
done.
Les différentes phases du GC sont indiquées ainsi que le nombre
d'objets traités.