프로그래밍Perl 개발자

Perl에서 사용되는 자동 메모리 정리(가비지 컬렉션) 메커니즘은 무엇이며, 순환 참조와 관련된 메모리 누수를 피하기 위한 방법은 무엇인가요? 그리고 수동 개입을 위한 기술은 무엇이 제안되나요?

Hintsage AI 어시스턴트로 면접 통과

답변

Perl에서는 변수와 데이터 구조에 대한 메모리를 참조 횟수 세기(reference counting) 메커니즘을 통해 관리합니다. 객체나 구조는 참조 횟수가 0이 될 때 해제됩니다.

그러나 이 메커니즘은 순환 참조를 조사하지 않습니다. 객체가 서로를 참조하면 참조 횟수가 0에 도달하지 않으며, 메모리가 해제되지 않습니다.

순환 참조를 정리하기 위해서는 다음과 같은 방법을 사용합니다:

  • 명시적인 참조 끊기 (객체 작업이 끝나면 참조 변수를 undef로 설정).
  • 모듈 Scalar::Util::weaken를 사용한 약한 참조(weak references). 약한 참조는 참조 횟수를 증가시키지 않아, 다른 강한 참조가 없으면 GC가 객체를 해제할 수 있습니다.

약한 참조 생성 예시:

use Scalar::Util 'weaken'; my $parent = {}; my $child = { parent => $parent }; $parent->{child} = $child; weaken($child->{parent}); # 이제 parent->child->parent가 정리를 방해하지 않음

속임수 질문

Perl은 Scalar::Util 모듈이나 수동 개입 없이 순환 참조를 "인식"하고 해제할 수 있나요?

아닙니다, Perl은 기본적으로 순환 구조를 자동으로 "수집"할 수 없으며, 이 메커니즘은 객체 그래프 구조 분석을 요구합니다(예: JVM 또는 Python의 GC와 같은). 따라서 항상 스스로 루프 정리에 신경 써야 합니다.

이 주제의 미세한 차이에 대한 실제 오류 사례


이야기

웹 애플리케이션의 세션 저장 서버에서 양방향 관계를 가진 User 객체들이 활발히 사용되었습니다. 수천 번 요청 후에 프로세스의 메모리가 증가하는 문제가 발생했습니다: $user->{session}->{user} = $user. 약한 참조 사용 후 역참조의 메모리 누수가 사라졌습니다.


이야기

LRU 알고리즘을 사용하는 캐시에서 객체들이 서로 링크된 체인을 가지고 있었습니다. 개발자들은 수동으로 링크를 초기화하지 않아, 서비스가 몇 일 동안 작동한 후 메모리가 급증하고 OOM으로 중단되었습니다.


이야기

복잡한 마이크로서비스에서 문서 저장 시 보고서를 생성할 때 eval 및 순환 참조를 가진 대규모 데이터 구조를 사용했습니다. 개발자들은 Perl의 자동 가비지 컬렉션을 기대했지만, 서버는 오래된 객체를 "기억"하여 일주일 후에 모든 사용 가능한 RAM을 소모했습니다. 진단 결과 순환 구조가 발견되었고, 각 보고서 후에 Scalar::Util을 사용했습니다.