我們對unset() 這個函數的作用的了解大概就是它可以銷毀一個變量,釋放內存,這種理解並沒有錯,可能就是不夠深入,接下來我通過幾個例子向大家展示下unset一個變量后真正發生的一些事情。以下的代碼是在linux+php7.1環境下運行
$s = str_repeat('1',256); $m = memory_get_usage(); unset($s); $mm = memory_get_usage(); echo $m-$mm;
輸出結果如下:
釋放了48個字節的內存,在說明結果之前我先帶大家了解下mermory_get_usage() 函數,官方的解釋是:當函數的參數不設置或者設置為false時返回的是分配給當前php腳本的內存量,如果設置為true的話返回的是系統分配總的內存尺寸,包括未使用的頁,那我們接着來看下當設置為true時的結果是怎樣的?
$s = str_repeat('1',256); $m = memory_get_usage(true); unset($s); $mm = memory_get_usage(true); echo $m-$mm;
輸出結果如下:
我們發現結果是0,那我們可以似乎可以得出一個結論是:unset掉一個變量后,當前腳本的內存量有所增加,內存被釋放,但是這部分內存沒有被我們的系統回收,那什么時候會被系統(OS)回收呢?
<?php $s = str_repeat('1',2100000); $m = memory_get_usage(true); unset($s); $mm = memory_get_usage(true); echo $m-$mm;
輸出結果如下:
我們發現這個結果不再是0,說明內存被系統回收了,也就是說我們unset掉的變量所占的內存大到一定程度時才會被系統回收,至於這個界限是多少,本人在不同的操作系統下運行的結果不同,可能與當前操作系統(OS)內存的大小和分配給當前腳本內存大小有關系。其實,當調用emalloc函數申請內存的時候php並不是簡單的想OS要內存,而是每次申請都會OS會分配一塊比較大的內存,當有申請者的時候再分配其中的一塊給它。另外,在測試中我們還發現釋放的內存有的時候小於我們申請的內存。
<?php $m0 = memory_get_usage(); echo '申請前:'.$m0."\r\n"; $s = str_repeat('1',100); $m = memory_get_usage(); echo '申請后:'.$m."\r\n"; unset($s); $mm = memory_get_usage(); echo '釋放后:'.$mm."\r\n";
輸出結果如下:
再來看個例子:
<?php $m0 = memory_get_usage(); echo '申請前:'.$m0."\r\n"; //$s = str_repeat('1',100);
$s = 'new string new string new string new string new string new string new string'; $m = memory_get_usage(); echo '申請后:'.$m."\r\n"; unset($s); $mm = memory_get_usage(); echo '釋放后:'.$mm."\r\n";
輸出結果如下:
這兩個例子的區別僅僅在於變量s的值一個是函數創建后再賦值的,一個是直接賦值的,第一個例子變量申請了192個字節,釋放的時候只釋放了160個字節,第二個例子申請前和釋放后是一樣的,那這是為什么呢?我們先看下php是怎么給我們分配內存的
1.為變量名分配內存,存入符號表
2.為變量值分配內存
在揭曉答案前在看兩個東東,一個是例1中變量s的zval結構,一個是例2中的zval結構:
發現通過函數創建的變量s的refcount=1,而直接賦值的變量s的refount=0,說明unset掉一個變量后只釋放了符號表s,s的值所占的內存並沒有被釋放。
好了,以上就是我對php unset()函數的總結。