ホームページ  >  記事  >  php教程  >  PHP ガベージ コレクション メカニズム

PHP ガベージ コレクション メカニズム

WBOY
WBOYオリジナル
2016-06-21 08:51:131021ブラウズ

各コンピューター言語には独自の自動ガベージ コレクション メカニズムがあるため、プログラマーはプログラムのメモリ割り当てについてあまり心配する必要はありません。PHP も例外ではありません。ただし、オブジェクト指向プログラミング (OOP) プログラミングでは、一部のオブジェクトを明示的に実行する必要があります。プログラムが実行メモリのオーバーフローを防ぐために破壊されます。
1. PHP ガベージ コレクション機構 (ガベージ コレクター (GC)
PHP では、このオブジェクトを指す変数がない場合、オブジェクトはガベージになります。 PHP はこれをメモリ内で破棄します。これは、メモリのオーバーフローを防ぐための PHP の GC ガベージ処理メカニズムです。
PHP スレッドが終了すると、現在占有されているすべてのメモリ領域が破棄され、現在のプログラム内のすべてのオブジェクトが同時に破棄されます。 GC プロセスは通常、セッションごとに実行を開始します。gc の目的は、セッション ファイルが期限切れになった後に自動的に破棄および削除することです。
2. __destruct /unset
__destruct() デストラクターは、ガベージ オブジェクトがリサイクルされるときに実行されます。
設定を解除すると、オブジェクトではなく、オブジェクトを指す変数が破壊されます。

3. セッションと GC
PHP の動作メカニズムにより、セッション情報を定期的にスキャンして期限切れかどうかを判断するデーモン スレッドがありません。有効なリクエストが発生した場合、PHP はグローバル変数セッションの値に基づいて続行するかどうかを決定します。 .gc_probability および session.gc_divisor は GC を有効にします。デフォルトでは、session.gc_probability=1、session.gc_divisor =100 は GC を開始する確率が 1% であることを意味します (つまり、100 件のリクエストのうち 1 つの gc のみが実行されます)。リクエストに応じて 100 のうちの 1 つがアクティブ化されます)。 GC の仕事は、すべてのセッション情報をスキャンし、現在の時刻からセッションの最終変更時刻を減算し、それを session.gc_maxlifetime パラメータと比較することです。生存時間が gc_maxlifetime (デフォルトは 24 分) を超える場合、セッションは終了します。削除される。
ただし、Web サーバーに複数のサイトがある場合、GC はセッションの処理中に予期しない結果を引き起こす可能性があります。その理由は、GC が動作しているときに、異なるサイトのセッションが区別されないためです。
では、このときどうやって解決すればいいのでしょうか?
1. session.save_path を変更するか、session_save_path() を使用して各サイトのセッションを専用ディレクトリ
に保存します。 2. GC 起動速度を指定します。当然、GC 起動速度が増加すると、それに応じてシステムのパフォーマンスが低下します。これはお勧めできません。
3. コード内の現在のセッションの生存時間を確認し、session_destroy() を使用して削除します。

以下の例を参照してください

例 1: gc.php
エラー報告(E_ALL); $a = '私はテストです。'; $b = & $a;
echo $b ."n"; ?>

言うまでもなく、% php -f gc.php の出力は非常に明確です:
hy0kl% php -f gc.php
私はテストです。

OK、次は:
例 2:
エラー報告(E_ALL); $a = '私はテストです。'; $b = & $a;
$b = '変更しますか?';
echo $a ."n"; echo $b ."n"; ?>
実行結果は依然として明白です:
hy0kl% php -f gc.php
変わりますか?
変わりますか?

ぜひご覧ください:
例 3:
エラー報告(E_ALL); $a = '私はテストです。'; $b = & $a;
設定を解除($a);

echo $a ."n"; echo $b ."n";
?>
考える必要がありますか?
hy0kl% php -f gc.php
注意: 未定義の変数: /usr/local/www/apache22/data/test/gc.php の 8 行目
私はテストです。
少し混乱していますか?

またお会いしましょう:
例 4:
エラー報告(E_ALL); $a = '私はテストです。'; $b = & $a;
unset($b);
echo $a ."n"; echo $b ."n";
?>
実際、例 3 を理解すると、これもそれに似ています。
hy0kl% php -f gc.php
私はテストです。
注意: 未定義の変数: b (/usr/local/www/apache22/data/test/gc.php の 9 行目
)
見てみましょう:
例 5:
エラー報告(E_ALL); $a = '私はテストです。'; $b = & $a;
$a = null;
echo '$a = '. $a ."n"; echo '$b = '. $b ."n"; ?>
最初の激しさは何ですか?
hy0kl% php -f gc.php
$a =
$b =
はい、これが出力結果です。すでに PHP GC を深く理解している PHP ユーザーにとっては、これに違和感はありません。正直、このコードを初めて実行したときは驚きましたが、これによって PHP についての理解が深まりました。 GC. わかりました。次に彼と協力する例を見てみましょう。

例 6:
$b = null;
echo '$a = '. $a ."n"; echo '$b = '. $b ."n"; ?>

GC と参照を詳しく分析してみましょう。
1. すべての例で、変数が作成されます。簡単に言うと、このプロセスはメモリ内にスペースを開き、そこに各ブロックを記録するための文字列「I am test.」を格納します。メモリの参照数を指定すると、このメモリの参照数が 1 増加し、$a という名前のラベル (変数) がこのメモリを指すために使用されるため、ラベル名に従ってメモリを操作すると便利です。

2. 変数 $a に対して & 演算を実行します。私の理解では、$a が指すメモリを見つけ、$b に同じ参照点を確立し、シンボル テーブル内の文字列 I am test を格納するメモリ ブロックを参照します。つまり、スクリプトがこの行に達すると、文字列「I am test.」を格納するメモリが 2 回参照されることになります。ここで強調すべき点は、& 操作がポインターではなく参照ポインターを確立するということです。 、PHP にはポインタの概念がありません。同時に、UNIX と同様のファイル ソフト リンクを提案している人もいます。これは、テスト対象の文字を保存するメモリであることをある程度理解できます。 、変数 $a と $b は実際のファイルに対して確立されたソフト リンクですが、これらは同じ実際のファイルを指しているため、例 2 で $b に値が割り当てられると、$a の値も同様であることがわかります。あるソフトリンクを渡すのと同じです。

3. 例 3 と 4 では、unset() 操作が実行されます。実際の実行結果によると、unset() は変数の参照を元のメモリに接続していないだけであることがわかります。それ自体が未定義の場合、呼び出し時に通知が発行され、シンボル テーブル内のそのメモリ部分の参照カウントが 1 減らされ、このメモリ部分を指す他の変数には影響しません。シンボル テーブル内のメモリの参照カウントが 0 の場合、PHP エンジンはこのメモリを再利用します。

PHPマニュアル
4.0.0 unset() 式になりました。 これはどういう意味ですか?
以下のコードとその結果を見てください:
エラー報告(E_ALL); $a = '私はテストです。'; $b = & $a;
設定を解除($a);
設定を解除($a);
設定を解除($a);

echo '$a = '. $a ."n"; echo '$b = '. $b ."n"; ?>
hy0kl% php -f gc.php

注意: 未定義の変数: /usr/local/www/apache22/data/test/gc.php の 10 行目
$a =
$b = 私はテストです。
最初の unset() 操作でポインターが切断されたため、後続の操作はシンボル テーブル内のメモリの参照カウントに影響を与えません。

4. 例 5 と 6 から、null 演算への代入は、変数が指すメモリのシンボル番号の参照カウントを直接 0 に設定することが明らかに結論付けられます。そうすると、このメモリは自然にゼロになります。エンジンによっていつ再利用されるかは不明です。他の情報を保存するためにすぐに使用される可能性もありますが、いずれの場合も、そのメモリ部分を指していたすべての変数は再び使用されなくなります。再利用されたメモリを操作できなくなり、変数に対して呼び出そうとすると null が返されます。

エラー報告(E_ALL); $a = '私はテストです。'; $b = & $a;
$b = null;
echo '$a = '. $a ."n"; echo '$b = '. $b ."n";
if (null === $a)
{ echo '$a は null です。'; } それ以外
{
echo '$a の型が不明です。'; }
?>
hy0kl% php -f gc.php
$a =
$b =
$a は null です。

要約すると、オープンソース製品のソース コードを見ると、比較的大きな一時変数、または使用後に呼び出されない再利用された情報が集中したり、null として表示されたりすることがよくある理由が十分に説明されています。 UNIX では、実際のファイルは直接破棄され、それを指すすべてのソフト リンクは自然に空のリンクになります。
以前にこれらの詳細について議論したときに、多くのことが当然だと思っていましたが、実際にテスト コードを実行してみると、ああ、これだ!
と気づきました。 紙の上で見たものはいずれ薄っぺらいものになってしまいますが、これをやらなければいけないということは必ず分かります。




声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。