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を追加しました。