首頁 後端開發 php教程 垃圾回收 PHP垃圾回收機制簡單說明

垃圾回收 PHP垃圾回收機制簡單說明

Jul 29, 2016 am 08:43 AM
垃圾回收

雖然自己也是PHP的學習者,但之前還真沒怎麼了解PHP內部的垃圾回收流程,只是在我們的程式碼中用了unset,null,mysql_close,__destruct等等一些函數去釋放物件防止記憶體溢出而已,所以上網GG下,找到了以下一些說明,作下記錄「PHP可以自動進行記憶體管理,清除不再需要的物件。PHP使用了引用計數(reference counting)這種單純的垃圾回收(garbage collection)機制。每個對像都內含一個引用計數器,每個reference連接到對象,計數器加1。不再需要使用這個對象,釋放其所佔的記憶體空間。」
眾所周知, 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 = '🎜>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/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 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.
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 =
hy0kl% php -f gc.php
$a =
hy0kl% php -f gc.php

$a =

hy0kl% php -f gc.php

$a =

hy0kl% php -f gc.php $a = hy0kl% php -f gc.php $a = hy0kl% php -f gc.php $a = hy0kl%。 >$b = $a is null. 綜上所述,充分說明了為什麼我們在看開源產品源碼的時候,常看到一些比較大的臨時變量,或使用完不再調用的重用資訊都會被集中或顯示的賦值為null 了.它相當於UNIX 中直接將真實文件幹掉了,所有指向它的軟鏈接自然成了空鏈了. 以上就介紹了垃圾回收 PHP垃圾回收機制簡單說明,包括了垃圾回收方面的內容,希望對PHP教程有興趣的朋友有所幫助。
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

C#開發中如何避免記憶體洩漏 C#開發中如何避免記憶體洩漏 Oct 08, 2023 am 09:36 AM

C#開發中如何避免記憶體洩漏

C#常見的記憶體管理問題及解決方法 C#常見的記憶體管理問題及解決方法 Oct 11, 2023 am 09:21 AM

C#常見的記憶體管理問題及解決方法

Java 函數中記憶體管理技術與安全性的關係是什麼? Java 函數中記憶體管理技術與安全性的關係是什麼? May 02, 2024 pm 01:06 PM

Java 函數中記憶體管理技術與安全性的關係是什麼?

PHP中的記憶體管理與垃圾回收技術 PHP中的記憶體管理與垃圾回收技術 May 11, 2023 am 08:33 AM

PHP中的記憶體管理與垃圾回收技術

Java開發中如何解決堆疊記憶體空間不足問題 Java開發中如何解決堆疊記憶體空間不足問題 Jun 29, 2023 am 11:11 AM

Java開發中如何解決堆疊記憶體空間不足問題

Java開發中如何避免網路連線外洩? Java開發中如何避免網路連線外洩? Jun 30, 2023 pm 01:33 PM

Java開發中如何避免網路連線外洩?

Python底層技術解析:如何實作垃圾回收機制 Python底層技術解析:如何實作垃圾回收機制 Nov 08, 2023 pm 07:28 PM

Python底層技術解析:如何實作垃圾回收機制

Python開發中遇到的記憶體管理問題及解決方案 Python開發中遇到的記憶體管理問題及解決方案 Oct 09, 2023 pm 09:36 PM

Python開發中遇到的記憶體管理問題及解決方案

See all articles