最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PHP GC回收機制實例詳解

 更新時間:2024年01月26日 09:06:29   作者:F12~  
GC的全稱是Garbage Collection也就是垃圾回收的意思,在PHP中,是使用引用計數和回收周期來自動管理內存對象的,當一個對象被設置為NULL,或者沒有任何指針指向時,他就會變成垃圾,被GC機制回收掉,這篇文章主要介紹了PHP GC回收機制詳解 ,需要的朋友可以參考下

前言

GC的全稱是Garbage Collection也就是垃圾回收的意思,在PHP中,是使用引用計數和回收周期來自動管理內存對象的,當一個對象被設置為NULL,或者沒有任何指針指向時,他就會變成垃圾,被GC機制回收掉。

環(huán)境配置

php.ini終配置好xdebug,xdebug_debug_zval是用來查看容器變量內容的函數

<?php 
$a = "F12";
xdebug_debug_zval("a");
?>

在PHP GC機制中,當程序終止時就會讓變量的refcount減1,如果refcount-1為0的話,就會銷毀回收該變量

引用計數

is_ref表示該變量是否被引用,操作系統(tǒng)學的好的同學應該很容易理解該內容

<?php 
  $a = "F12";
  $b = &$a;
  xdebug_debug_zval("a");
?>
# 運行結果
a: (refcount=2, is_ref=1)='F12'

$b是$a的引用,所以is_ref=1,同時refcount也會加1,因為此時是有兩個變量的(兩變量指向同一個地址),所以銷毀時要讓refcount減2。
當變量是array類型時,也是一樣的規(guī)則

<?php 
  $a = "F12";
  $arr = array(0=>"test", 1=>&$a);
  xdebug_debug_zval("arr");
?>
# 運行結果
arr: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)='test', 1 => (refcount=2, is_ref=1)='F12')

如果我們在引用前將$a銷毀會發(fā)生什么?

<?php 
  $a = "F12";
  unset($a);
  $arr = array(0=>"test", 1=>&$a);
  xdebug_debug_zval("a");
  xdebug_debug_zval("arr");
?>
# 運行結果
a: (refcount=2, is_ref=1)=NULL
arr: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)='test', 1 => (refcount=2, is_ref=1)=NULL)
<?php 
  $a = "F12";
  $arr = array(0=>"test", 1=>&$a);
  unset($a);
  xdebug_debug_zval("a");
  xdebug_debug_zval("arr");
?>
# 運行結果
a: no such symbol
arr: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)='test', 1 => (refcount=1, is_ref=1)='F12')

第一種情況,$a沒有被銷毀,因為在之后又引用了$a,所以$a只是指向了一個NULL,第二種情況就把$a銷毀了

PHP GC在反序列化中的使用

一個簡單的demo

<?php
class gc{
    public $num;
    public function __construct($num)
    {
        $this->num=$num;
        echo "construct(".$num.")"."\n";
    }
    public function __destruct()
    {
        echo "destruct(".$this->num.")"."\n";
    }
}
$a=new gc(1);
$b=new gc(2);
$c=new gc(3);
# 運行結果
construct(1)
construct(2)
construct(3)
destruct(3)
destruct(2)
destruct(1)

先創(chuàng)建的對象最后銷毀,看看變量的內容情況:

可以看到refcount為1,所以當程序結束時,減1就會被回收
如果我們不把new的gc對象賦值給$a會怎樣?

<?php
class gc{
    public $num;
    public function __construct($num)
    {
        $this->num=$num;
        echo "construct(".$num.")"."\n";
    }
    public function __destruct()
    {
        echo "destruct(".$this->num.")"."\n";
    }
}
new gc(1);
$b=new gc(2);
$c=new gc(3);
# 運行結果
construct(1)
destruct(1)
construct(2)
construct(3)
destruct(3)
destruct(2)

可以看到第一個gc對象,創(chuàng)建完就被回收了,因為沒被其它變量引用,它的refcount一開始就是0,所以直接被回收

繞過Exception異常

思路一

一個簡單的demo:

<?php
class gc{
    public $num;
    public function __construct($num)
    {
        $this->num=$num;
    }
    public function __destruct()
    {
        echo "Hello World!";
    }
}
$a = new gc(1);
$ser = serialize($a);
$b = unserialize($ser);
throw new Exception("F12 is bad");

正常來說會輸出一個Hello World!,但是因為觸發(fā)了異常,所以對象并沒有被回收

我們修改一下代碼:

<?php
class gc{
    public $num;
    public function __construct($num)
    {
        $this->num=$num;
    }
    public function __destruct()
    {
        echo "Hello World!";
    }
}
$a = array(0=>new gc(1),1=>1);
$ser = serialize($a);
echo $ser;
$ser = 'a:2:{i:0;O:2:"gc":1:{s:3:"num";i:1;}i:0;i:1;}';
$b = unserialize($ser);
throw new Exception("F12 is bad");

這里我們我們修改序列化的內容,將$a[0]隨便指向誰,從而使new的gc對象沒有引用的變量,所以觸發(fā)提前回收,跟上面舉的直接new gc,并不賦值是一個道理

思路二

這種方法更加簡單粗暴,我們只需要讓序列化的數據出錯,那么當反序列化時出錯時,也會讓該對象提前回收

<?php
class gc{
    public $num;
    public function __construct($num)
    {
        $this->num=$num;
    }
    public function __destruct()
    {
        echo "Hello World!";
    }
}
$a = new gc(1);
$ser = serialize($a);
echo $ser;
$ser = 'O:2:"gc":1:{s:3:"num";i:1;';
$b = unserialize($ser);
throw new Exception("F12 is bad");

這里我們刪去一個},依然輸出了Hello World!

到此這篇關于PHP GC回收機制詳解 的文章就介紹到這了,更多相關PHP GC回收機制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • PHP開發(fā)api接口安全驗證的實例講解

    PHP開發(fā)api接口安全驗證的實例講解

    下面小編就為大家分享一篇PHP開發(fā)api接口安全驗證的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • PHP調用wsdl文件類型的接口代碼分享

    PHP調用wsdl文件類型的接口代碼分享

    本文給大家分享了一個PHP調用wsdl文件類型的接口代碼,非常的簡單也很實用,有相關需求的小伙伴們可以直接拿去用的。
    2014-11-11
  • PHP驗證終端類型是否為手機的簡單實例

    PHP驗證終端類型是否為手機的簡單實例

    下面小編就為大家?guī)硪黄狿HP驗證終端類型是否為手機的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 微信公眾號判斷用戶是否已關注php代碼解析

    微信公眾號判斷用戶是否已關注php代碼解析

    這篇文章主要大家詳細解析了微信公眾號判斷用戶是否已關注php代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Thinkphp自定義代碼生成工具及用法說明(附下載地址)

    Thinkphp自定義代碼生成工具及用法說明(附下載地址)

    這篇文章主要介紹了Thinkphp自定義代碼生成工具及用法說明,簡單分析了自定義代碼生成工具的作用及用法,并附帶了下載地址,需要的朋友可以參考下
    2016-05-05
  • Laravel 5.5基于內置的Auth模塊實現(xiàn)前后臺登陸詳解

    Laravel 5.5基于內置的Auth模塊實現(xiàn)前后臺登陸詳解

    最近在使用laravel5.5,利用其實現(xiàn)了一個功能,下面分享給大家,這篇文章主要給大家介紹了關于Laravel 5.5基于內置的Auth模塊如何實現(xiàn)前后臺登陸的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧。
    2017-12-12
  • PHP基于yii框架實現(xiàn)生成ICO圖標

    PHP基于yii框架實現(xiàn)生成ICO圖標

    本文給大家分享了2則php生成ICO圖標的代碼,第一款是基于YII框架實現(xiàn)的,第二款是純php編寫,都非常的不錯,有需要的小伙伴可以參考下
    2015-11-11
  • ThinkPHP中自定義錯誤頁面和提示頁面實例

    ThinkPHP中自定義錯誤頁面和提示頁面實例

    這篇文章主要介紹了ThinkPHP中自定義錯誤頁面和提示頁面的方法,以一個完整的實例形式詳細講述了ThinkPHP實現(xiàn)自定義錯誤提示與跳轉頁面的方法,是非常常見的實用技巧,需要的朋友可以參考下
    2014-11-11
  • thinkPHP的表達式查詢用法詳解

    thinkPHP的表達式查詢用法詳解

    這篇文章主要介紹了thinkPHP的表達式查詢用法,結合實例形式分析了thinkPHP表達式查詢的格式及相關運算符用法,需要的朋友可以參考下
    2016-09-09
  • PHP、Java des加密解密實例

    PHP、Java des加密解密實例

    這篇文章主要介紹了PHP、Java des加密解密實例,des加密是對稱加密中在互聯(lián)網應用的比較多的一種加密方式,本文分別給出了PHP和JAVA版本的實現(xiàn)代碼,需要的朋友可以參考下
    2015-04-04

最新評論

康定县| 阿尔山市| 丰镇市| 红桥区| 安顺市| 宁安市| 乃东县| 博白县| 新昌县| 东乡县| 海伦市| 芮城县| 罗山县| 达日县| 天峨县| 阜城县| 芦山县| 法库县| 怀宁县| 白朗县| 鄂尔多斯市| 镇康县| 苏尼特左旗| 自治县| 河曲县| 尼勒克县| 阿尔山市| 旌德县| 环江| 抚顺县| 营口市| 普洱| 股票| 凤山县| 桐庐县| 乐安县| 屏南县| 通化县| 外汇| 如皋市| 马公市|