検索
ホームページphp教程php手册PHPのガベージコレクションメカニズムの簡単な説明

PHPのガベージコレクションメカニズムの簡単な説明

Jun 13, 2016 pm 12:14 PM
php学ぶ内部リサイクルごみどうやって機構単純自分の説明する

私も PHP の学習者ですが、これまでは、コード内で unset、null、mysql_close、__destruct などの関数を使用して、メモリ オーバーフローを防ぐためにオブジェクトを解放するだけでした。私はインターネット上の GG で次の手順を見つけて記録しました: 「PHP は自動的にメモリを管理し、不要になったオブジェクトを消去できます。PHP は参照カウントと呼ばれる単純なガベージ コレクション メカニズムを使用します。各オブジェクトに参照カウンターが含まれるたびに、各参照はオブジェクトに接続されます。参照がリビング スペースから離れるか、NULL に設定されると、カウンターは 1 ずつ減ります。オブジェクトの参照カウンターがゼロになると、PHP はこのオブジェクトがゼロになることを認識します。必要になり、それが占有しているメモリ空間が解放されます。”

众所周知, PHP 引擎本身是用 C 写的,提到 C 不能不提的就是 GC(垃圾回收).通过 PHP 手册 我们了解到, PHP 引擎会自动进行 GC 动作.那么我们不禁要问,到底它是怎么回收的, & 引用操作是不是指针, unset() 了一个变量时它是不是真的被回收了呢?这些看似手册有提及的问题,如果仔细分析会发现,远没有那么简单泛泛.也许有人会跳出来说:看 PHP 源码不就知道了.是的,等你通读了 PHP 源码后这个问题肯定不在话下了,然本篇要仅从 PHP 本身来分析这些看似平常却被忽视的小细节,当然了,其中难免水平所限,有所疏漏,热烈欢迎广大 phper 来共同讨论.

首先咱先看到例子,最简单不过的执行流程了:
Example 1: gc.php
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

echo $b ." ";
?>

不用说 % php -f gc.php 输出结果非常明了:
hy0kl% php -f gc.php
I am test.

好,下一个:
Example 2:
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

$b = 'I will change?';

echo $a ." ";
echo $b ." ";
?>
执行结果依然很明显:
hy0kl% php -f gc.php
I will change?
I will change?

君请看:
Example 3:
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

unset($a);

echo $a ." ";
echo $b ." ";
?>
是不是得想一下下呢?
hy0kl% php -f gc.php
Notice: Undefined variable: a in /usr/local/www/apache22/data/test/gc.php on line 8
I am test.
有点犯迷糊了吗?

君再看:
Example 4:
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

unset($b);

echo $a ." ";
echo $b ." ";
?>
其实如果 Example 3 理解了,这个与之异曲同工.
hy0kl% php -f gc.php
I am test.
Notice: Undefined variable: b in /usr/local/www/apache22/data/test/gc.php on line 9

君且看:
Example 5:
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

$a = null;

echo '$a = '. $a ." ";
echo '$b = '. $b ." ";
?>
猛的第一感觉是什么样的?
hy0kl% php -f gc.php
$a =
$b =
没错,这就是输出结果,对 PHP GC 已有深入理解的 phper 不会觉得有什么奇怪,说实话,当我第一次运行这段代码时很意外,却让我对 PHP GC 有更深刻的理解了.那么下面与之同工的例子自然好理解了.

Example 6:
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

$b = null;

echo '$a = '. $a ." ";
echo '$b = '. $b ." ";
?>

OK,如果上面的例子的结果对看官来说无任何细节可言,那您可关闭本窗口了,欢迎有空再来!

下面我们来详细分析 GC 与引用.
1. 所有例子中,创建了一个变量,这个过程通俗一点讲:是在内存中开辟了一块空间,在里面存放了一个字符串 I am test. . PHP 内部有个符号表,用来记录各块内存引用计数,那么此时会将这块内存的引用计数 加 1,并且用一个名为 $a 的标签(变量)指向这块内存,方便依标签名来操作内存.

2. 对变量 $a 进行 & 操作,我的理解是找到 $a 所指向的内存,并为 $b 建立同样的一引用指向,并将存放字符串 I am test. 的内存块在符号表中引用计数 加 1.换言之,我们的脚本执行到这一行的时候,存放字符串 I am test. 的那块内存被引用了两次.这里要强调的是, & 操作是建立了引用指向,而不是指针, PHP 没有指针的概念!同时有人提出说类似于 UNIX 的文件软链接.可以在一定程度上这么理解: 存放字符 I am test. 的那块内存是我们的一个真实的文件,而变量 $a 与 $b 是针对真实文件建立的软链接,但它们指向的是同一个真实文件. So, 我们看到,在 Example 2 中给 $b 赋值的同时, $a 的值也跟着变化了.与通过某一软链操作了文件类似.

3. 在 Example 3 与 4 中,进行了 unset() 操作.根据实际的执行结果,可以看出: unset() 只是断开这个变量对它原先指向的内存的引用,使变量本身成为没有定义过空引用,所在调用时发出了 Notice ,并且使那块内存在符号表中引用计数 减 1,并没有影响到其他指向这块内存的变量.换言之,只有当一块内存在符号表中的引用计数为 0 时, PHP 引擎才会将这块内存回收.
PHP 手册
4.0.0 unset() became an expression. (In PHP 3, unset() would always return 1).
这意味着什么?
看看下面的代码与其结果:
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

unset($a);
unset($a);
unset($a);

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

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

4. 例 5 と 6 から、代入 null 操作は非常に暴力的であると明確に結論付けることができます。シンボル内のメモリが 0 に設定されると、このメモリはエンジンによって自然に再利用され、他の情報を保存するためにすぐに使用されるか、または二度と使用されない可能性があります。 , いずれの場合も、そのメモリを指す元の変数はすべて、再利用されたメモリ上で操作できなくなり、そのメモリを呼び出そうとした変数は

error_reporting を返します。 (E_ALL);
$a = '私はテストです。';

$b = null; . $a . " ";
echo '$b = '." ";

if (null === $a)
echo '$a null.';
} else
{
echo '$a の型が不明です。';
}
?> php -f gc.php
$a =
$b =
$a は null

要約すると、オープンソース製品のソース コードを見ると、比較的多くの場合、大きな一時変数、または使用後に呼び出されなくなった再利用情報は集中するか null として表示されます。これは、UNIX で実際のファイルを直接強制終了するのと同等であり、そのファイルを指すすべてのソフト リンクは当然空のリンクになります。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)