Perl은 메모리를 자동으로 관리합니다: 변수가 더 이상 참조되지 않을 때 파괴됩니다(참조 계수). Perl의 가비지 컬렉터는 전형적인 추적 GC를 사용하지 않고 참조 계수에 의존합니다.
장점:
free()와 같이).단점 및 함정:
my $a = {}; my $b = {}; $a->{b} = $b; $b->{a} = $a; # 두 변수는 정리 시 해제되지 않으며, perl은 이를 삭제할 수 없음
이러한 문제를 해결하기 위해 Scalar::Util::weaken 모듈을 사용하여 참조를 "약화"할 수 있습니다:
use Scalar::Util 'weaken'; my $a = {}; my $b = {}; $a->{b} = $b; weaken($b->{a} = $a);
모든 명시적 변수가 삭제될 경우 Perl의 모든 객체는 제거되나요, 내부에 참조가 있어도?
답변: 아닙니다! 객체들이 서로를 참조하고 있을 경우(순환을 생성하면), Perl은 이를 삭제하지 않으며 수동으로 순환을 끊거나 Scalar::Util::weaken을 통해 연결을 약화해야 합니다.
이야기
대규모 연결을 처리하는 장기 데몬을 개발하는 과정에서, 프로그래머들은 IoHandle 객체와 관련된 이벤트 핸들러 간에 순환 참조를 놓쳤습니다. 몇 시간의 작업 후 메모리가 기하급수적으로 증가했고 — Devel::Leak 분석만이 문제를 드러냈습니다.
이야기
대량 파일 파싱의 ETL 프로세스에서 수백만 개의 임시 해시 요소가 누적되어 프로세스가 "정지"되었습니다. 부모에 대한 중첩 참조가 하나의 요소에 저장되어 있었고(3단계 연결을 위해), 메모리 해제가 일어나지 않았습니다. 스키마의 일부 재구성이 메모리 누수를 피하는 데 도움이 되었습니다.
이야기
프로그래머들은 MapReduce 엔진에서 클로저를 사용하여 익명 서브프로그램에 맥락의 복사본을 저장했습니다. 이 서브프로그램들은 "누수"되어 — 배치 작업이 끝난 후에도 메모리가 해제되지 않았으며, 맥락이 자신을 참조하고 있었습니다. 정확한 파괴를 위해 명시적
undef를 추가했습니다.