Perl utilise une gestion automatique de la mémoire via des compteurs de références (reference counting). Lorsque vous construisez des structures imbriquées (par exemple, des tableaux à l'intérieur de hachages), chaque élément de tout conteneur augmente ou diminue le nombre de références à un objet donné. Lorsque le nombre de références devient nul, la mémoire est automatiquement libérée.
Une attention particulière doit être portée aux références cycliques, que Perl ne peut pas libérer tout seul — c'est un piège classique lors de la manipulation de structures imbriquées. Perl prend également en charge les références faibles via le module Scalar::Util, ce qui permet de rompre les cycles : une référence faible n'augmente pas le compteur de références.
my %hash_of_arrays; $hash_of_arrays{"nums"} = [1,2,3]; $hash_of_arrays{"words"} = ["apple", "banana"];
my $a = {}; my $b = { next => $a }; $a->{next} = $b; # Ici un cycle se forme dump($a); # Utilisez Data::Dumper pour visualiser la structure
Pour éviter les fuites, on utilise des références faibles :
use Scalar::Util qw(weaken); $a->{next} = $b; weaken($a->{next}); # Maintenant $a->{next} est une référence faible
Que se passe-t-il avec la mémoire si on supprime uniquement les variables externes contenant des références cycliquement liées entre un tableau et un hachage en Perl ?
Réponse correcte : Le compteur de références de aucun des objets ne sera remis à zéro, car chacun fera référence à l'autre ; la mémoire ne sera pas libérée — il y aura une fuite ! Il est nécessaire de rompre manuellement les cycles (par exemple, via des références faibles).
my $arr = []; my $h = { arr => $arr }; push @$arr, $h; # Maintenant $arr et $h forment un cycle. Après undef $arr; undef $h; la mémoire n'est pas libérée.
Histoire
Histoire
Histoire
Lors de la mise en œuvre du caching dans une application CGI, il a été décidé d'utiliser des structures interconnectées complexes (tableaux et hachages). En raison d'une mauvaise mise à zéro des anciennes valeurs, l'un des éléments du tableau continuait à référencer le hachage de la structure entière, et la mémoire n'était pas libérée entre les requêtes HTTP, ce qui causait une augmentation de la mémoire du processus Apache.