一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

PHP垃圾回收機制簡單說明

雖然自己也是php的學習者,但之前還真沒怎么了解php內部的垃圾回收流程,只是在我們的代碼中用了unset,null,mysql_close,__destruct等等一些函數去釋放對象防止內存溢出而已,所以上網GG下,找到了以下一些說明,作下記錄“php可以自動進行內存管理,清除不再需要的對象。php使用了引用計數(reference counting)這種單純的垃圾回收(garbage collection)機制。每個對象都內含一個引用計數器,每個reference連接到對象,計數器加1。當reference離開生存空間或被設為NULL,計數器減1。當某個對象的引用計數器為零時,php知道你將不再需要使用這個對象,釋放其所占的內存空間。”

眾所周知, php 引擎本身是用 C 寫的,提到 C 不能不提的就是 GC(垃圾回收).通過 php 手冊 我們了解到, php 引擎會自動進行 GC 動作.那么我們不禁要問,到底它是怎么回收的, & 引用操作是不是指針, unset() 了一個變量時它是不是真的被回收了呢?這些看似手冊有提及的問題,如果仔細分析會發現,遠沒有那么簡單泛泛.也許有人會跳出來說:看 php 源碼不就知道了.是的,等你通讀了 php 源碼后這個問題肯定不在話下了,然本篇要僅從 php 本身來分析這些看似平常卻被忽視的小細節,當然了,其中難免水平所限,有所疏漏,熱烈歡迎廣大 phper 來共同討論.

首先咱先看到例子,最簡單不過的執行流程了:
Example 1: gc.php
<?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:
<?php
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:
<?php
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:
<?php
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:
<?php
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:
<?php
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).
這意味著什么?
看看下面的代碼與其結果:
<?php
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

Notice: Undefined variable: a in /usr/local/www/apache22/data/test/gc.php on line 10
$a =
$b = I am test.
第一次 unset() 的操作已經斷開了指向,所以后繼的操作不會對符號表的任何內存的引用記數造成影響了.

4. 通過 Example 5 & 6 可以明確無誤得出: 賦值 null 操作是相當猛的,它會直接將變量所指向的內存在符號號中的引用計數置 0, 那這塊內存自然被引擎回收了,至于何時被再次利用不得而知,有可能馬上被用作存儲別的信息,也許再也沒有使用過.但是無論如何,原來所有指向那塊內存變量都將無法再操作被回收的內存了,任何試圖調用它的變量都將返回 null.

<?php
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

$b = null;

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

if (null === $a)
{
echo '$a is null.';
} else
{
echo 'The type of $a is unknown.';
}
?>
hy0kl% php -f gc.php
$a =
$b =
$a is null.

綜上所述,充分說明了為什么我們在看開源產品源碼的時候,常看到一些比較大的臨時變量,或使用完不再調用的重用信息都會被集中或顯示的賦值為 null 了.它相當于 UNIX 中直接將真實文件干掉了,所有指向它的軟鏈接自然成了空鏈了.

php技術PHP垃圾回收機制簡單說明,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 在线看的成人性视频 | 色综合色综合色综合色综合 | 五月激情站 | 欧美一区二区三区激情啪啪 | 伊人精品久久久大香线蕉99 | 国产精品久久国产精麻豆99网站 | 亚洲另类图 | 亚洲视频99 | 国产精品丝袜 | 美女一级毛片毛片在线播放 | 亚洲天堂日韩在线 | 久久久精品国产四虎影视 | 在线一区二区三区 | 久热精品6 | 色视频在线观看 | 亚洲日本一区二区三区在线不卡 | 免费国产小视频 | 亚洲色图视频在线观看 | 黄色的视频免费 | 色宅男中文字幕亚洲专区 | 国产手机精品自拍视频 | 国产成人精品高清在线观看99 | 亚洲精品成人a在线观看 | www.色午夜| 婷婷香蕉 | 国产的鲁啊鲁 | 国产成人91 | 国产精品1 | 中文字幕视频二区 | 在线播放人成午夜免费视频 | 成人久久精品 | 一级毛片国产真人永久在线 | 碰91精品国产91久久婷婷 | 视色4se影院在线观看 | 久久中文字幕久久久久 | 美女视频一区二区 | 午夜视频福利在线观看 | 国产综合激情在线亚洲第一页 | 中文字幕不卡一区 二区三区 | 国产大片在线观看 | 五月激情综合丁香色婷婷 |