1. 程式人生 > >PHP--記憶體洩漏

PHP--記憶體洩漏

一個PHP指令碼。一般都不用考慮記憶體洩漏和垃圾回收的問題,因為指令碼很快就執行完退出了,每個頁面處理結束,新建的simple_html_dom物件就會被銷燬。 
但當執行時間長,資料量大的時候,程式執行一段時間後,PHP指令碼就佔用了過多記憶體,然後報錯:

PHP Fetal error:Allowed memory size of 1342117728 bytes exhausted
1
PHP垃圾回收機制
PHP5.3之前使用的垃圾回收機制是單純的“引用計數”,也就是每個記憶體物件都分配了一個計數器,當記憶體物件被變數引用時,計數器+1,當變數引用撤掉時,計數器-1,當計數器等於0時,表明記憶體物件沒有被使用,該記憶體物件則進行銷燬,垃圾回收完成。 
“引用計數”存在問題是當兩個或多個物件互相引用形成環狀後,記憶體物件的計數器不會消減為0,這一組記憶體物件沒用時,不能進行回收,導致記憶體洩漏。 
從PHP5.3開始,使用了新的垃圾回收機制,在引用計數的基礎上,實現了複雜的演算法,來檢測記憶體物件中引用環的存在,以避免記憶體洩漏。

檢查記憶體是否洩漏
可以簡單的通過呼叫memory_get_usage函式檢視記憶體使用情況來判斷;memory_get_usage函式返回的記憶體使用資料據說不是很準確,可以使用xdebug擴充套件來獲得更準確的記憶體使用情況。

int memory_get_usage ([ bool $real_usage = false ] )
//返回當前分配給你的PHP指令碼的記憶體量,單位是位元組(byte);
//real_usage如果設定為true,獲取系統分配總的記憶體尺寸,包括未使用的頁。如果未設定或者設定FALSE,僅僅報告實際使用記憶體量。
1
2
3
記憶體洩漏例項
class A{
    private $b;
    function __construct()
    {
        $this->b = new B($this);
    }
    function __destruct()
    {
        // TODO: Implement __destruct() method.
        echo "A destruct";
    }
}

class B {
    private $a;
    function __construct($a)
    {
        $this->a = $a;
    }
    function __destruct()
    {
        // TODO: Implement __destruct() method.
        echo "B destruct";
    }
}

for ($i = 0;;$i++) {
    $a = new A();
    echo memory_get_usage()."\n";
}
原文:https://blog.csdn.net/Charles91/article/details/72357518