PHP unset() 詳解


我們對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()函數的總結。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM