phpのごみ回収メカニズムについて

2746 ワード

先週金曜日の今頃、新東家に面接に行ったところ、phpのゴミ回収メカニズム(garbage collect、GC)について話していましたが、その時頭の中で思いついた漠然とした概念は、相手が使わないときに回収されることでした.帰ってきてから、この問題を解決しようと思って、今日の午前中はちょうど暇だったので、時間を割いて小さな研究をしました.
まずsessionのGCメカニズムについて述べ、具体的にはphpを見ることができる.iniのこの説明
; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using
; gc_probability/gc_divisor. Where session.gc_probability is the numerator
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request.

GCはセッション中のgcに基づいていますprobability/gc_divisorの確率で起動し、gc_probabilityは1,gc_divisorが1000であれば、GCを起動する確率は千分の一しかありません.つまり、1000回のセッションでは、GCを起動できるのは一度だけです.ここでgc_probabilityとgc_divisorはphpを構成することができる.中sessiongc_俺達は...gc_divisorの値を変更したり、phpスクリプトでini_を使用したりすることができます.set(session.gc_probability,1)およびini_set(session.gc_divisor,100)で再設定します.
GCが起動すると、すべてのセッション情報がスキャンされ、セッションが最後に変更する時間を現在の時間から減算し、セッションと同じになります.gc_maxlifetime(一般的に1440秒、すなわち24分)パラメータを比較し、生存時間がgc_を超えるとmaxlifetimeは、セッションを削除します.
変数のGCメカニズムについてお話しします.phpは自動的にメモリ管理を行い、不要なオブジェクトをクリアします.phpは参照カウント(reference counting)という単純なGC機構を用いた.各オブジェクトには参照カウンタが含まれており、各参照はオブジェクトに接続され、カウンタには1が加算されます.referenceが生存空間を離れるかNULLに設定されると、カウンタは1を減算する.オブジェクトのリファレンスカウンタがゼロの場合、phpはこのオブジェクトを使用する必要がなくなり、メモリ領域を解放することを知っています.
簡単な例をいくつか挙げます
eg1.
#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

echo $a; // good

echo $b; // good

この例は、メモリに空間を開き、値が文字列goodであり、$aという変数がこのメモリを指すとともに、php内部に各ブロックのメモリ参照カウントを記録するシンボルテーブルがあり、このメモリの参照カウントに1を加算すると理解できる.次に$b=&$a、これは参照伝達値、すなわち$bの変数もこのメモリを指し、同時に参照カウントに1を加え、このとき2となる.
eg2
#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

$a = 'test';

echo $a; // test

echo $b; // test

$aと$bは同じメモリを指しているので、$bの値を変更すると、$aの値も変わります.
eg3
#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

#refcount=1
unset($a);

echo $a; // Notice: Undefined variable: a in E:\www\test\1408\15.php on line 16

echo $b; // good

ここを見て、ある友达は少し疑問に思っているはずですが、どうして$bがまだ価値があるのですか.実はunsetという操作は$aが指すメモリの参照を切断し、そのブロック内にシンボルテーブルの参照カウントを1減らしただけで、他のメモリを指す変数には影響しないので、$bの値はgoodです.phpエンジンは、シンボルテーブルに存在する参照カウントが0の場合にのみ、このメモリを回収します.
eg4
#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

#refcount=0
$a = null;

echo $a; // 

echo $b; // 

$aをnullに割り当てると、そのブロックメモリへの参照が直接0に設定され、そのメモリも解放されます.つまり、$aと$b変数に相当する値はnullになります.元のメモリは解放されているからです.
簡単に説明しますが、詳しく知りたい場合は、PHPカーネル探索:新しいゴミ回収メカニズムの説明を参照してください.