天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

PHP垃圾回收機(jī)制簡(jiǎn)單說明

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

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

首先咱先看到例子,最簡(jiǎn)單不過的執(zhí)行流程了:
Example 1: gc.php
<?php
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

echo $b ." ";
?>

不用說 % php -f gc.php 輸出結(jié)果非常明了:
hy0kl% php -f gc.php
I am test.

好,下一個(gè):
Example 2:
<?php
error_reporting(E_ALL);
$a = 'I am test.';
$b = & $a;

$b = 'I will change?';

echo $a ." ";
echo $b ." ";
?>
執(zhí)行結(jié)果依然很明顯:
hy0kl% php -f gc.php
I will change?
I will change?

君請(qǐng)看:
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.
有點(diǎn)犯迷糊了嗎?

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

unset($b);

echo $a ." ";
echo $b ." ";
?>
其實(shí)如果 Example 3 理解了,這個(gè)與之異曲同工.
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 =
沒錯(cuò),這就是輸出結(jié)果,對(duì) php GC 已有深入理解的 phper 不會(huì)覺得有什么奇怪,說實(shí)話,當(dāng)我第一次運(yùn)行這段代碼時(shí)很意外,卻讓我對(duì) php GC 有更深刻的理解了.那么下面與之同工的例子自然好理解了.

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

$b = null;

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

OK,如果上面的例子的結(jié)果對(duì)看官來說無任何細(xì)節(jié)可言,那您可關(guān)閉本窗口了,歡迎有空再來!

下面我們來詳細(xì)分析 GC 與引用.
1. 所有例子中,創(chuàng)建了一個(gè)變量,這個(gè)過程通俗一點(diǎn)講:是在內(nèi)存中開辟了一塊空間,在里面存放了一個(gè)字符串 I am test. . php 內(nèi)部有個(gè)符號(hào)表,用來記錄各塊內(nèi)存引用計(jì)數(shù),那么此時(shí)會(huì)將這塊內(nèi)存的引用計(jì)數(shù) 加 1,并且用一個(gè)名為 $a 的標(biāo)簽(變量)指向這塊內(nèi)存,方便依標(biāo)簽名來操作內(nèi)存.

2. 對(duì)變量 $a 進(jìn)行 & 操作,我的理解是找到 $a 所指向的內(nèi)存,并為 $b 建立同樣的一引用指向,并將存放字符串 I am test. 的內(nèi)存塊在符號(hào)表中引用計(jì)數(shù) 加 1.換言之,我們的腳本執(zhí)行到這一行的時(shí)候,存放字符串 I am test. 的那塊內(nèi)存被引用了兩次.這里要強(qiáng)調(diào)的是, & 操作是建立了引用指向,而不是指針, php 沒有指針的概念!同時(shí)有人提出說類似于 UNIX 的文件軟鏈接.可以在一定程度上這么理解: 存放字符 I am test. 的那塊內(nèi)存是我們的一個(gè)真實(shí)的文件,而變量 $a 與 $b 是針對(duì)真實(shí)文件建立的軟鏈接,但它們指向的是同一個(gè)真實(shí)文件. So, 我們看到,在 Example 2 中給 $b 賦值的同時(shí), $a 的值也跟著變化了.與通過某一軟鏈操作了文件類似.

3. 在 Example 3 與 4 中,進(jìn)行了 unset() 操作.根據(jù)實(shí)際的執(zhí)行結(jié)果,可以看出: unset() 只是斷開這個(gè)變量對(duì)它原先指向的內(nèi)存的引用,使變量本身成為沒有定義過空引用,所在調(diào)用時(shí)發(fā)出了 Notice ,并且使那塊內(nèi)存在符號(hào)表中引用計(jì)數(shù) 減 1,并沒有影響到其他指向這塊內(nèi)存的變量.換言之,只有當(dāng)一塊內(nèi)存在符號(hào)表中的引用計(jì)數(shù)為 0 時(shí), php 引擎才會(huì)將這塊內(nèi)存回收.
php 手冊(cè)
4.0.0 unset() became an expression. (In php 3, unset() would always return 1).
這意味著什么?
看看下面的代碼與其結(jié)果:
<?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() 的操作已經(jīng)斷開了指向,所以后繼的操作不會(huì)對(duì)符號(hào)表的任何內(nèi)存的引用記數(shù)造成影響了.

4. 通過 Example 5 & 6 可以明確無誤得出: 賦值 null 操作是相當(dāng)猛的,它會(huì)直接將變量所指向的內(nèi)存在符號(hào)號(hào)中的引用計(jì)數(shù)置 0, 那這塊內(nèi)存自然被引擎回收了,至于何時(shí)被再次利用不得而知,有可能馬上被用作存儲(chǔ)別的信息,也許再也沒有使用過.但是無論如何,原來所有指向那塊內(nèi)存變量都將無法再操作被回收的內(nèi)存了,任何試圖調(diào)用它的變量都將返回 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.

綜上所述,充分說明了為什么我們?cè)诳?a href=/yuedu/kaiyuan/ target=_blank class=infotextkey>開源產(chǎn)品源碼的時(shí)候,常看到一些比較大的臨時(shí)變量,或使用完不再調(diào)用的重用信息都會(huì)被集中或顯示的賦值為 null 了.它相當(dāng)于 UNIX 中直接將真實(shí)文件干掉了,所有指向它的軟鏈接自然成了空鏈了.

php技術(shù)PHP垃圾回收機(jī)制簡(jiǎn)單說明,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 亚洲欧美人成视频在线 | 日韩精品 电影一区 亚洲高清 | 国产精一品亚洲二区在线播放 | xxxx18动漫 | 性奴公司 警花 | 久久亚洲人成网站 | 在线观看国产亚洲 | 国产精品永久在线 | av在线不卡中文网 | 香蕉人人超人人超碰超国产 | 九九99热久久精品在线6 | 俄罗斯videosbest8 | 欧洲最大无人区免费高清完整版 | 亚洲一区二区三区乱码在线欧洲 | 成人毛片100部免费看 | 久久国产露脸老熟女熟69 | 日本 一二三 不卡 免费 | 国产精品久久人妻无码蜜 | 午夜理伦片免费 | 动漫美女被到爽了流漫画 | 久久久精品免费视频 | 日本熟妇乱妇熟色A片蜜桃亚洲 | 日韩精品一区二区三区AV在线观看 | SM双性精跪趴灌憋尿调教H | 少妇邻居内射在线 | 坠落的丝袜美人妻 | 久久久久夜 | 永久午夜福利视频一区在线观看 | 中俄两军在日本海等上空战略巡航 | 久久人妻少妇嫩草AV無碼 | 精品国产乱码久久久久久软件 | 狠狠躁天天躁小说 | 亚洲综合色在线视频久 | 国产精品成人A蜜柚在线观看 | 翁熄性放纵交换01 | 国产精品人妻一区免费看8C0M | 小柔的性放荡羞辱日记动漫 | 一个吃奶两个添下面H | 三级黄色视屏 | 三级黄色在线 | 国产成人免费 |