Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Gestion de la mémoire en Perl (garbage collector)

3 réponses
Avatar
Nathan
Bonjour,

J'ai une question concernant la gestion de la mémoire par perl (garbage
collector).

Soit le code suivant:

my %hash = ();
{ # Accolade pour limiter la portée des variables
my @lambda = ();
{ # Accolade pour limiter la portée des variables
my $var1 = 1;
my $var2 = 2;
$lambda[0] = \$var1;
$lambda[1] = \$var2;
}
$hash{"lambda"} = \@lambda;
}
%hash = undef;


La ligne "%hash = undef" permet-elle de vraiment libérer toute la mémoire?
C'est à dire, les références vers la variable @lambda et les variables
$var1 et $var2 sont-elle libérées ou faut-il le faire manuellement ?

$ref_tab = $hash{"lambda"};
$ref_tab->[0] = undef;
$ref_tab->[1] = undef;
$hash{"lambda"} = undef;
%hash = undef;

Merci

Nathan

3 réponses

Avatar
Paul Gaborit
À (at) Wed, 19 Dec 2007 16:55:56 +0100,
Nathan écrivait (wrote):
Bonjour,

J'ai une question concernant la gestion de la mémoire par perl (garbage
collector).

Soit le code suivant:

my %hash = ();
{ # Accolade pour limiter la portée des variables
my @lambda = ();
{ # Accolade pour limiter la portée des variables
my $var1 = 1;
my $var2 = 2;
$lambda[0] = $var1;
$lambda[1] = $var2;
}
$hash{"lambda"} = @lambda;
}


Pour obtenir le même résultat, on peut écrire plus simplement :

my %hash (
lambda => [1, 2],
);


%hash = undef;


Qu'on peut écrire :

undef %hash;

La ligne "%hash = undef" permet-elle de vraiment libérer toute la mémoire?
C'est à dire, les références vers la variable @lambda et les variables
$var1 et $var2 sont-elle libérées ou faut-il le faire manuellement ?


Ce n'est pas vraiment $var1, $var2 et @lambda qui sont référencés mais
bien leurs valeurs.

En fait toutes les valeurs tiennent un décompte des références qui
pointent vers elles. Dès que ce décompte tombe à zéro, la valeur est
libérée (c'est un ramasse-miettes assez basiques mais très efficace et
simple à mettre en oeuvre). Dans le cas présent, ça marche : tous les
décomptes tombent à zéro.

Le défaut de cet algorithme apparaît lorsqu'il y a des références
circulaires. Dans ce cas, il faut casser les cycles soi-même avant de
pouvoir tout libérer. Sinon on se retrouve avec un ensemble de valeurs
qui se référencent elle-mêmes (circulairement) sans qu'on puisse y
accèder depuis notre programme puisque plus aucune variable ne
conserve de références vers ces valeurs. On peut voir cela comme une
fuite mémoire...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Paul Gaborit
À (at) Wed, 19 Dec 2007 17:49:50 +0100,
Paul Gaborit écrivait (wrote):
À (at) Wed, 19 Dec 2007 16:55:56 +0100,
Nathan écrivait (wrote):
Bonjour,

J'ai une question concernant la gestion de la mémoire par perl (garbage
collector).

Soit le code suivant:

my %hash = ();
{ # Accolade pour limiter la portée des variables
my @lambda = ();
{ # Accolade pour limiter la portée des variables
my $var1 = 1;
my $var2 = 2;
$lambda[0] = $var1;
$lambda[1] = $var2;
}
$hash{"lambda"} = @lambda;
}


Pour obtenir le même résultat, on peut écrire plus simplement :

my %hash > (
lambda => [1, 2],
);


Désolé, j'ai oublié un niveau :

my %hash (
lambda => [1, 2],
);

Mais ça ne change rien pour le reste... ;-)

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>


Avatar
Nathan
Re bonjour,

Exactement la réponse qu'il me fallait.
Merci beaucoup pour ta réponse rapide, complète et efficace.

Nathan

À (at) Wed, 19 Dec 2007 17:49:50 +0100,
Paul Gaborit écrivait (wrote):
À (at) Wed, 19 Dec 2007 16:55:56 +0100,
Nathan écrivait (wrote):
Bonjour,

J'ai une question concernant la gestion de la mémoire par perl (garbage
collector).

Soit le code suivant:

my %hash = ();
{ # Accolade pour limiter la portée des variables
my @lambda = ();
{ # Accolade pour limiter la portée des variables
my $var1 = 1;
my $var2 = 2;
$lambda[0] = $var1;
$lambda[1] = $var2;
}
$hash{"lambda"} = @lambda;
}
Pour obtenir le même résultat, on peut écrire plus simplement :


my %hash >> (
lambda => [1, 2],
);


Désolé, j'ai oublié un niveau :

my %hash > (
lambda => [1, 2],
);

Mais ça ne change rien pour le reste... ;-)