簡體   English   中英

PHP的“未設置”構造如何在內部工作?

[英]How does PHP's 'unset' construct work internally?

前言:我確實知道“未設置”在用戶領域的工作方式,但是我想了解它在內部的工作方式。

zval結構上調用unset時,它將減少參考計數器(refcount__gc)。 當refcount__gc達到0時,該變量不再使用,可以刪除。 問題是它是否總是立即完成,或者在某些情況下可以稍后由垃圾回收器完成?

我發現了兩個矛盾的說法:

unset()就像它的名字所說的一樣-取消設置變量。 它不會強制立即釋放內存。 PHP的垃圾收集器將在其認為合適的情況下進行此操作-出於故意,因為無論如何都不需要這些CPU周期,或者直到腳本耗盡內存之前(無論哪種情況先發生)。 -Stackoverflow答案提及2009 php.net文檔

相反:

當refcount達到零時,zval被銷毀,並且它持有的任何內存現在都是空閑的- 更好的理解PHP的垃圾回收,2012年文章

那么從PHP 5.3和PHP 5.5來看,哪一個是正確的呢? 如果可能的話,也許您可​​以在PHP源代碼中提供指向未設置定義的鏈接。 謝謝!

TL; DR

兩種說法都是正確的。

讓我解釋。 (至少從PHP 5.0開始,這是事實(以前,我不知道)。現在出現了phpng,它進行了根本性的更改,但是仍然使用此原理。)


圓形垃圾收集器

循環垃圾收集器僅用於循環引用。 通常當兩個對象包含彼此的引用時才使用它們。

因為在這種情況下refcount__gc永遠不會降為零…在其他地方仍然有一些參考,普通的ZEND_UNSET_ *(星號為ARRAY,OBJ或VAR)無法取消設置。 因此,它必須等待垃圾收集器。

並且由於性能原因,垃圾回收器僅被定期調用。

php-src定義

您是否要求提供ZEND_UNSET_VAR的定義? http://lxr.php.net/xref/PHP_5_6/Zend/zend_vm_def.h#4069

這是減少refcount等的主要功能: http : //lxr.php.net/xref/PHP_5_6/Zend/zend_execute.h#74

哪一個是正確的?

因此,如果refcount為零,我們可以確定沒有任何鏈接可以釋放它。 (第二條語句:只是在談論refcount == 0的情況)

但是,如果它不為零,則將變量標記為稍后由循環垃圾收集器檢查。 (第一句話: 不一定立即釋放)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM