Perl은 참조 카운트를 통한 자동 메모리 관리를 사용합니다. 중첩 구조(예: 해시 내 배열)를 만들 때, 컨테이너의 각 요소는 특정 객체에 대한 참조 수를 증가시키거나 감소시킵니다. 참조 수가 0이 되면 메모리가 자동으로 해제됩니다.
특히 Perl은 자동으로 해제할 수 없는 순환 참조에 주의해야 합니다. 이것은 중첩 구조를 사용할 때의 전형적인 함정입니다. Perl은 또한 Scalar::Util 모듈을 통한 약한 참조를 지원하여 순환을 끊을 수 있습니다. 약한 참조는 참조 카운트를 증가시키지 않습니다.
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; # 여기서 순환이 발생합니다. dump($a); # Data::Dumper를 사용하여 구조를 표시합니다.
메모리 누수를 피하기 위해 약한 참조를 사용할 수 있습니다:
use Scalar::Util qw(weaken); $a->{next} = $b; weaken($a->{next}); # 이제 $a->{next}는 약한 참조입니다.
Perl에서 외부 변수를 삭제하여 해시와 배열 간에 순환 참조를 가진 경우 메모리에 어떤 일이 발생합니까?
정답: 어떤 객체의 참조 카운트도 0이 되지 않으므로 서로 참조하며, 메모리는 해제되지 않으므로 메모리 누수가 발생합니다! 순환을 수동으로 끊어야 합니다(예: 약한 참조를 통해).
my $arr = []; my $h = { arr => $arr }; push @$arr, $h; # 이제 $arr과 $h가 순환을 형성합니다. 이후 undef $arr; undef $h; 메모리가 해제되지 않습니다.
이야기
이야기
이야기
CGI 애플리케이션 내에서 캐싱을 구현하면서 복잡한 상호 연결된 구조(배열과 해시)를 사용하기로 했습니다. 이전 값을 잘못 초기화함으로 인해 배열의 한 요소가 전체 구조의 해시를 계속 참조하게 되었고, 이는 HTTP 요청 간에 메모리가 해제되지 않도록 하여 Apache 프로세스의 메모리가 증가하는 원인이 되었습니다.