国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHP的垃圾回收機制-引用計數基本知識(5.3)

dreambei / 2510人閱讀

摘要:后者的例子在給巨大的一個知名的組件庫的模板組件做單元測試時,就可能會出現問題。

PHP的垃圾回收機制

垃圾回收器,全稱Garbage Collection,簡稱GC,5.3版本之前 只是簡單判斷變量的zval的refcount是否為0,是的話就釋放,不是直至進程結束(隱藏著變量內存溢出的風險).

如果你已經安裝了? Xdebug,你能通過調用函數 xdebug_debug_zval()顯示"refcount"和"is_ref"的值。

引用計數基本知識 1、一個zval變量容器:
內容
類型
is_ref 是個bool值,用來標識這個變量是否是屬于引用集合(reference set) zval變量容器中還有一個內部引用計數機制,來優化內存使用
refcount 指向這個zval變量容器的變量(也稱符號即symbol)個數 所有的符號存在一個符號表中,其中每個符號都有作用域(scope),那些主腳本(比如:通過瀏覽器請求的的腳本)和每個函數或者方法也都有作用域。

當一個變量被賦常量值時,就會生成一個zval變量容器

1、 生成一個新的zval容器

參考上面的定義,分別是:

生成的變量容器,其中:

類型 string

值 new string

is_ref false

Refcount 1

2、增加一個zval的引用計數

把一個變量賦值給另一變量將增加引用次數(refcount).

類型 string

值 new string

is_ref true

Refcount 2

引用次數是2,因為同一個變量容器被變量 a 和變量 b關聯.當沒必要時,php不會去復制已生成的變量容器。變量容器在”refcount“變成0時就被銷毀. 當任何關聯到某個變量容器的變量離開它的作用域(比如:函數執行結束),或者對變量調用了函數 unset()時,”refcount“就會減1.

3、 減少引用計數


a: (refcount=3, is_ref=0)="new string"
a: (refcount=1, is_ref=0)="new string"

如果我們現在執行 unset($a);,包含類型和值的這個變量容器就會從內存中刪除。

4、復合類型(Compound Types) ?

當考慮像 array和object這樣的復合類型時,事情就稍微有點復雜. 與 標量(scalar)類型的值不同,array和 object類型的變量把它們的成員或屬性存在自己的符號表中。這意味著下面的例子將生成三個zval變量容器。

 "life", "number" => 42 );
xdebug_debug_zval( "a" );
?>

輸出

a: (refcount=1, is_ref=0)=array (
   "meaning" => (refcount=1, is_ref=0)="life",
   "number" => (refcount=1, is_ref=0)=42
)

看圖說話

這三個zval變量容器是: a,meaning和 number。增加和減少”refcount”的規則和上面提到的一樣. 下面, 我們在數組中再添加一個元素,并且把它的值設為數組中已存在元素的值:

添加一個已經存在的元素到數組中

 "life", "number" => 42 );
$a["life"] = $a["meaning"];
xdebug_debug_zval( "a" );
?>

輸出

a: (refcount=1, is_ref=0)=array (
   "meaning" => (refcount=2, is_ref=0)="life",
   "number" => (refcount=1, is_ref=0)=42,
   "life" => (refcount=2, is_ref=0)="life"
)

有圖有真相

從以上的xdebug輸出信息,我們看到原有的數組元素和新添加的數組元素關聯到同一個"refcount"2的zval變量容器. 盡管 Xdebug的輸出顯示兩個值為"life"的 zval 變量容器,其實是同一個。 函數xdebug_debug_zval()不顯示這個信息,但是你能通過顯示內存指針信息來看到。

刪除數組中的一個元素,就是類似于從作用域中刪除一個變量. 刪除后,數組中的這個元素所在的容器的“refcount”值減少,同樣,當“refcount”為0時,這個變量容器就從內存中被刪除,下面又一個例子可以說明:

 "life", "number" => 42 );
$a["life"] = $a["meaning"];
unset( $a["meaning"], $a["number"] );
xdebug_debug_zval( "a" );
?>

輸出

a: (refcount=1, is_ref=0)=array (
   "life" => (refcount=1, is_ref=0)="life"
)

現在,當我們添加一個數組本身作為這個數組的元素時,事情就變得有趣,下個例子將說明這個。例中我們加入了引用操作符,否則php將生成一個復制。

把數組作為一個元素添加到自己

輸出

a: (refcount=2, is_ref=1)=array (
   0 => (refcount=1, is_ref=0)="one",
   1 => (refcount=2, is_ref=1)=...
)

看圖說話

能看到數組變量 (a) 同時也是這個數組的第二個元素(1) 指向的變量容器中“refcount”為 2。上面的輸出結果中的"..."說明發生了遞歸操作, 顯然在這種情況下意味著"..."指向原始數組。

跟剛剛一樣,對一個變量調用unset,將刪除這個符號,且它指向的變量容器中的引用次數也減1。所以,如果我們在執行完上面的代碼后,對變量$a調用unset, 那么變量 $a 和數組元素 "1" 所指向的變量容器的引用次數減1, 從"2"變成"1". 下例可以說明:


輸出

(refcount=1, is_ref=1)=array (
   0 => (refcount=1, is_ref=0)="one",
   1 => (refcount=1, is_ref=1)=...
)

看圖說話

2、清理變量容器的問題(Cleanup Problems) ?

盡管不再有某個作用域中的任何符號指向這個結構(就是變量容器),由于數組元素“1”仍然指向數組本身,所以這個容器不能被清除 。因為沒有另外的符號指向它,用戶沒有辦法清除這個結構,結果就會導致內存泄漏。慶幸的是,php將在腳本執行結束時清除這個數據結構,但是在php清除之前,將耗費不少內存。如果你要實現分析算法,或者要做其他像一個子元素指向它的父元素這樣的事情,這種情況就會經常發生。當然,同樣的情況也會發生在對象上,實際上對象更有可能出現這種情況,因為對象總是隱式的被引用。

如果上面的情況發生僅僅一兩次倒沒什么,但是如果出現幾千次,甚至幾十萬次的內存泄漏,這顯然是個大問題。這樣的問題往往發生在長時間運行的腳本中,比如請求基本上不會結束的守護進程(deamons)或者單元測試中的大的套件(sets)中。后者的例子:在給巨大的eZ(一個知名的PHP Library) 組件庫的模板組件做單元測試時,就可能會出現問題。有時測試可能需要耗用2GB的內存,而測試服務器很可能沒有這么大的內存。

PHP手冊

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31004.html

相關文章

  • PHPer面試指南-PHP

    摘要:本書的地址篇收集了一些常見的基礎進階面試題,基礎的面試題不再作答。如何實現持久化持久化,將在內存中的的狀態保存到硬盤中,相當于備份數據庫狀態。相當于備份數據庫接收到的命令,所有被寫入的命令都是以的協議格式來保存的。 本書的 GitHub 地址:https://github.com/todayqq/PH... PHP 篇收集了一些常見的基礎、進階面試題,基礎的面試題不再作答。 基礎篇 ...

    stackvoid 評論0 收藏0
  • 【轉】淺談PHP5中垃圾回收算法(Garbage Collection)演化

    摘要:所有這些類型,在內部統一用一個叫做的結構表示,在源代碼中這個結構名稱為。的具體定義在源代碼的文件中,下面是相關代碼的摘錄。 【轉】淺談PHP5中垃圾回收算法(Garbage Collection)的演化 前言 PHP是一門托管型語言,在PHP編程中程序員不需要手工處理內存資源的分配與釋放(使用C編寫PHP或Zend擴展除外),這就意味著PHP本身實現了垃圾回收機制(Garbage C...

    AdolphLWQ 評論0 收藏0
  • PHP回收周期

    摘要:原文回收周期,增加一篇論文在底部。就是說,僅僅在引用計數減少到非零值時,才會產生垃圾周期。如果他們是循環引用周期的一部分,將永不能被清除進而導致內存泄漏。這個函數將返回使用這個算法回收的周期數。引用計數系統中的同步周期回收 原文:回收周期(Collecting Cycles) ,增加一篇論文在底部。 以下過程僅對數組和對象類型起作用。 傳統上,像以前的 php 用到的引用計數內存機制,...

    Astrian 評論0 收藏0
  • 能讓你更早下班Python垃圾回收機制

    摘要:內部通過引用計數機制來統計一個對象被引用的次數。下一步,就該被我們的垃圾回收器給收走了。而我們垃圾回收機制只有當引用計數為的時候才會釋放對象。以空間換時間的方法提高垃圾回收效率。 人生苦短,只談風月,談什么垃圾回收。據說上圖是某語言的垃圾回收機制。。。我們寫過C語言、C++的朋友都知道,我們的C語言是沒有垃圾回...

    pumpkin9 評論0 收藏0
  • PHP垃圾回收機制

    摘要:在中算法,當節點緩沖區滿了之后,垃圾分析算法就會啟動,并且會釋放掉發現的垃圾,從而回收內存。在編程中程序員不需要手動處理內存資源分配與釋放,意味著本身實現了垃圾回收處理機制。 PHP是一種弱類型的腳本語言,弱類型不表示PHP變量沒有類型的區別,PHP變量有8種原始類型:四種標量類型: boolean(布爾值) integer(整型) float(浮點型) 兩種復合類型: arra...

    luck 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<