垃圾回收 PHP垃圾回收機制簡單說明
雖然自己也是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教程有興趣的朋友有所幫助。
熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

C#開發中如何避免記憶體洩漏,需要具體程式碼範例記憶體洩漏是軟體開發過程中常見的問題之一,特別是在使用C#語言進行開發時。記憶體洩漏會導致應用程式佔用越來越多的記憶體空間,最終導致程式運行緩慢甚至崩潰。為了避免記憶體洩漏,我們需要注意一些常見的問題並採取相應措施。及時釋放資源在C#中,使用完資源後一定要及時釋放它們,尤其是涉及文件操作、資料庫連線和網路請求等資源。可以

C#中常見的記憶體管理問題及解決方法,需要具體程式碼範例在C#開發中,記憶體管理是一個重要的問題,不正確的記憶體管理可能會導致記憶體洩漏和效能問題。本文將向讀者介紹C#中常見的記憶體管理問題,並提供解決方法,並給出具體的程式碼範例。希望能幫助讀者更理解和掌握記憶體管理技術。垃圾回收器不及時釋放資源C#中的垃圾回收器(GarbageCollector)負責自動釋放不再使

PHP作為一種廣泛使用的腳本語言,為了在運行時確保高效執行,具有獨特的記憶體管理和垃圾回收技術。本文將簡單介紹PHP記憶體管理和垃圾回收的原理與實作方式。一、PHP記憶體管理的原理PHP的記憶體管理採用了引用計數(ReferenceCounting)來實現,這種方式是現代化的語言中比較常見的記憶體管理方式之一。當一個變數被使用時,PHP會為其分配一段內存,並將這段內

Java中的記憶體管理涉及自動記憶體管理,使用垃圾回收和引用計數來分配、使用和回收記憶體。有效的記憶體管理對於安全性至關重要,因為它可以防止緩衝區溢位、野指標和記憶體洩漏,從而提高程式的安全性。例如,透過正確釋放不再需要的對象,可以避免記憶體洩漏,從而提高程式效能並防止崩潰。

Python開發中遇到的記憶體管理問題及解決方案摘要:在Python開發過程中,記憶體管理是一個重要的問題。本文將討論一些常見的記憶體管理問題,並介紹相應的解決方案,包括引用計數、垃圾回收機制、記憶體分配、記憶體洩漏等。並提供了具體的程式碼範例來幫助讀者更好地理解和應對這些問題。引用計數Python使用引用計數來管理記憶體。引用計數是一種簡單而有效率的記憶體管理方式,它記錄每

Python底層技術解析:如何實現垃圾回收機制,需要具體程式碼範例引言:Python作為一種高階程式語言在開發中極為方便且靈活,但是其底層實作卻是相當複雜的。本文將聚焦在Python的垃圾回收機制,包括垃圾回收的原理、演算法以及具體的實作程式碼範例。希望透過本文對Python垃圾回收機制的解析,讀者能夠更深入了解Python底層技術。一、垃圾回收原理首先,我

如何使用Go語言進行內存優化與垃圾回收Go語言作為一門高效能、並發、效率高的程式語言,對於內存的優化和垃圾回收有著很好的支援。在開發Go程式時,合理地管理和最佳化記憶體使用,能夠提高程式的效能和可靠性。使用適當的資料結構在Go語言中,選擇合適的資料結構對記憶體的使用有很大的影響。例如,對於需要頻繁新增和刪除元素的集合,使用鍊錶代替陣列可以減少記憶體碎片的產生。另外,

Java作為一門廣泛使用的程式語言,由於其自動記憶體管理機制,特別是垃圾回收機制的存在,使得開發人員無需過多關注記憶體的分配和釋放。然而,在一些特殊情況下,例如處理大數據或執行複雜的演算法時,Java程式可能會遇到堆疊記憶體空間不足的問題。本文將討論如何解決這個問題。一、了解堆記憶體空間堆記憶體是Java虛擬機器(JVM)中指派給Java程式執行時間所使用的記憶體空間。它存儲了
