這篇文章帶給大家的內容是關於php底層原理的垃圾回收機制的介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
php垃圾回收機制,對於PHPer來說是一個不陌生但是又不是很熟悉的內容。那麼php是怎麼實現對不需要的記憶體進行回收的呢?
php變數的內部儲存結構
首先還是需要了解下基礎知識,以便於垃圾回收原理內容的理解。大家都知道php是由C寫而成的,所以php變數的內部儲存結構也會和C語言相關,也就是zval的結構體:
struct _zval_struct { union { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; zend_object_value obj; zend_ast *ast; } value; //变量value值 zend_uint refcount__gc; //引用计数内存中使用次数,为0删除该变量 zend_uchar type; //变量类型 zend_uchar is_ref__gc; //区分是否是引用变量 };
從上面結構體內容可以看出每一個php變數都會由變數類型、value值、引用計數次數和是否是引用變數四部分組成
註:上面zval結構體是php5.3版本之後的結構,php5.3之前因為沒有引進新的垃圾回收機制,即GC,所以命名也沒有_gc;而php7版本之後由於性能問題所以改寫了zval結構,這裡不再表述
#引用計數原理
了解了php變量的內部儲存結構之後,我們再了解下php變數賦值相關的原理和早期垃圾回收機制
變數容器
非array和object變數
每次都會常數賦值給一個變數時,都會產生一個變數容器
範例:
$a = '许铮的技术成长之路'; xdebug_debug_zval('a')
結果:
a: (refcount=1, is_ref=0)='许铮的技术成长之路'
array和object變數
會產生元素個數1的變數容器
範例:
$b = [ 'name' => '许铮的技术成长之路', 'number' => 3 ]; xdebug_debug_zval('b')
結果:
b: (refcount=1, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 'number' => (refcount=1, is_ref=0)=3)
賦值原理(寫時複製技術)
#了解常數賦值之後,接下來我們從記憶體角度思考變數之間的賦值
舉例:
$a = [ 'name' => '许铮的技术成长之路', 'number' => 3 ]; //创建一个变量容器,变量a指向给变量容器,a的ref_count为1 $b = $a; //变量b也指向变量a指向的变量容器,a和b的ref_count为2 xdebug_debug_zval('a', 'b'); $b['name'] = '许铮的技术成长之路1';//变量b的其中一个元素发生改变,此时会复制出一个新的变量容器,变量b重新指向新的变量容器,a和b的ref_count变成1 xdebug_debug_zval('a', 'b');
結果:
a: (refcount=2, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 'number' => (refcount=1, is_ref=0)=3) b: (refcount=2, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 'number' => (refcount=1, is_ref=0)=3) a: (refcount=1, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 'number' => (refcount=1, is_ref=0)=3) b: (refcount=1, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路1', 'number' => (refcount=1, is_ref=0)=3)
所以,當變數a賦值給變數b的時候,並沒有立刻生成一個新的變數容器,而是將變數b指向了變數a指向的變數容器,即記憶體"共享";而當變數b其中一個元素改變時,才會真正發生變數容器複製,這就是寫入時複製技術
引用計數清除0
當變數容器的ref_count計數清除時,表示該變數容器就會被銷毀,實現了記憶體回收,這也是php5.3版本之前的垃圾回收機制
範例:
$a = "许铮的技术成长之路"; $b = $a; xdebug_debug_zval('a'); unset($b); xdebug_debug_zval('a');
結果:
a: (refcount=2, is_ref=0)='许铮的技术成长之路' a: (refcount=1, is_ref=0)='许铮的技术成长之路'
循環引用引發的記憶體外洩問題
#但是php5.3版本之前的垃圾回收機制存在一個漏洞,即當數組或物件內部子元素引用其父元素,而此時如果發生了刪除其父元素的情況,此變數容器並不會被刪除,因為其子元素還在指向該變數容器,但由於所有作用域內都沒有指向該變數容器的符號,所以無法被清除,因此會發生記憶體洩漏,直到該腳本執行結束
舉例:
$a = array( 'one' ); $a[] = &$a; xdebug_debug_zval( 'a' );
由於此範例不好輸出結果,用圖表示,如圖:
範例:
unset($a); xdebug_debug_zval('a');
如圖:
新的垃圾回收機制
php5.3版本之後引入根緩衝機制,即php啟動時預設設定指定zval數量的根緩衝區(預設為10000),當php發現有存在循環引用的zval時,就會把其投入到根緩衝區,當根緩衝區達到配置檔案中的指定數量(預設是10000)後,就會進行垃圾回收,以此解決循環引用導致的記憶體洩漏問題
確認為垃圾的準則
#1、如果引用計數減少到零,所在變數容器將被清除(free),不屬於垃圾
2、如果一個zval 的引用計數減少後還大於0,那麼它就會進入垃圾週期。其次,在一個垃圾週期中,透過檢查引用計數是否減1,並且檢查哪些變數容器的引用次數是零,來發現哪一部分是垃圾。
總結
垃圾回收機制:
1、以php的引用計數機制為基礎(php5.3以前只有該機制)
2、同時使用根緩衝區機制,當php發現有存在循環引用的zval時,就會把其投入到根緩衝區,當根緩衝區達到配置檔案中的指定數量後,就會進行垃圾回收,以此解決循環引用導致的記憶體洩漏問題(php5.3開始引入該機制)
以上是php底層原理的垃圾回收機制的介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

要保護應用免受與會話相關的XSS攻擊,需採取以下措施:1.設置HttpOnly和Secure標誌保護會話cookie。 2.對所有用戶輸入進行輸出編碼。 3.實施內容安全策略(CSP)限制腳本來源。通過這些策略,可以有效防護會話相關的XSS攻擊,確保用戶數據安全。

优化PHP会话性能的方法包括:1.延迟会话启动,2.使用数据库存储会话,3.压缩会话数据,4.管理会话生命周期,5.实现会话共享。这些策略能显著提升应用在高并发环境下的效率。

theSession.gc_maxlifetimesettinginphpdeterminesthelifespanofsessiondata,setInSeconds.1)它'sconfiguredinphp.iniorviaini_set().2)abalanceisesneededeededeedeedeededto toavoidperformance andunununununexpectedLogOgouts.3)

在PHP中,可以使用session_name()函數配置會話名稱。具體步驟如下:1.使用session_name()函數設置會話名稱,例如session_name("my_session")。 2.在設置會話名稱後,調用session_start()啟動會話。配置會話名稱可以避免多應用間的會話數據衝突,並增強安全性,但需注意會話名稱的唯一性、安全性、長度和設置時機。

會話ID應在登錄時、敏感操作前和每30分鐘定期重新生成。 1.登錄時重新生成會話ID可防會話固定攻擊。 2.敏感操作前重新生成提高安全性。 3.定期重新生成降低長期利用風險,但需權衡用戶體驗。

在PHP中設置會話cookie參數可以通過session_set_cookie_params()函數實現。 1)使用該函數設置參數,如過期時間、路徑、域名、安全標誌等;2)調用session_start()使參數生效;3)根據需求動態調整參數,如用戶登錄狀態;4)注意設置secure和httponly標誌以提升安全性。

在PHP中使用會話的主要目的是維護用戶在不同頁面之間的狀態。 1)會話通過session_start()函數啟動,創建唯一會話ID並存儲在用戶cookie中。 2)會話數據保存在服務器上,允許在不同請求間傳遞數據,如登錄狀態和購物車內容。

如何在子域名間共享會話?通過設置通用域名的會話cookie實現。 1.在服務器端設置會話cookie的域為.example.com。 2.選擇合適的會話存儲方式,如內存、數據庫或分佈式緩存。 3.通過cookie傳遞會話ID,服務器根據ID檢索和更新會話數據。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

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

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

WebStorm Mac版
好用的JavaScript開發工具