Perl uses automatic memory management through reference counting. When you build nested structures (for example, arrays inside hashes), each element of any container increases or decreases the number of references to a given object. When the number of references becomes zero, the memory is automatically freed.
Particular attention should be paid to cyclic references, which Perl cannot free on its own — this is a classic trap when working with nested structures. Perl also supports weak references through the Scalar::Util module, which allows breaking cycles: a weak reference does not increment the reference count.
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; # Here a cycle occurs dump($a); # Use Data::Dumper to view the structure
To avoid leaks, weak references are used:
use Scalar::Util qw(weaken); $a->{next} = $b; weaken($a->{next}); # Now $a->{next} is a weak reference
What will happen to memory if in Perl only the external variables containing cyclically linked references between an array and a hash are deleted?
Correct answer: The reference count of neither object will become zero, as each will refer to the other; the memory will not be freed — there will be a leak! Cycles need to be broken manually (for example, through weak references).
my $arr = []; my $h = { arr => $arr }; push @$arr, $h; # Now $arr and $h form a cycle. After undef $arr; undef $h; memory is not freed.
History
History
History
When implementing caching within a CGI application, complex interrelated structures (arrays and hashes) were decided to be used. Due to incorrect nullification of old values, one of the elements of the array continued to reference the hash of the entire structure, and memory was not freed between HTTP requests, causing the memory usage of the Apache process to grow.