php7垃圾回收算法

前言

  • 首先回顧一下引用計數(shù)法:引用計數(shù)(reference counting)
    在引用計數(shù)算法中,對象的存活性可以通過引用關(guān)系的創(chuàng)建或刪除直接判定,而無需像追蹤式回收器那樣先通過堆遍歷找出所有的存活對象,然后再反向確定出未遍歷到的垃圾對象。
    //todo
  • 對于基于最基本的引用計數(shù)法的垃圾回收算法優(yōu)點是非常快,但是缺點是循環(huán)引用的時候沒法回收會造成內(nèi)存泄露。而php垃圾回收算法是基于上述論文的引用計數(shù)+局部延時標(biāo)記的垃圾回收算法。

第一部分

先看偽代碼

//  S 代表php中的對象
//purple    紫色表示對象在PossibleRoot 集合,但是在該集合中的不一定是紫色    
// buffered(S)    S是否在 PossibleRoot 集合    
// black  黑色表示對象正在被使用或者已經(jīng)被回收了(不需要管了)
//gray    棕色表示對象可能被回收
//white  白色表示對象要被回收
//RC        ReferenceCount  引用計數(shù)
//color(S)       S 的顏色
 
//當(dāng)new 一個對象的時候,這時候不需要垃圾回收,這是最簡單的情況
Increase(S){
      RC(S) = RC(S) + 1;        //引用計數(shù) +1
      color(S) = black;           // 顏色染成黑色
 }
//當(dāng)刪除一個指向S 的引用的時候
Decrease(S){
      RC(S) = RC(S) - 1;        //引用計數(shù)減1
      if (RC(S) == 0)               // 當(dāng)引用計數(shù)變?yōu)? 時候
           Release(S);              // 調(diào)用釋放函數(shù)Release()
      else
           PossibleRoot(S) ;    //放入可能回收的PossibleRoot區(qū)域并染色成紫色purple   
}      


Release(S){
for T in children(S)      // 遞歸調(diào)用減少子節(jié)點的引用
       Decrement(T);
color(S)= black         // 之后將該S節(jié)點染成黑色 (將被回收或者不需要回收 , 這里是前者)
if (! buffered(S))     // 判斷S 是否在PossibleRoot集合,在這個集合的在稍后的統(tǒng)一處理,
        Free(S);      //不在該集合且引用計數(shù)為0可以直接回收 
}
PossibleRoot(S){
if (color(S)!= purple)
       color(S)= purple
       if (! buffered(S)){
            buffered(S)= true
            append S to Roots
        }
}

第二部分

//主要是這個CollectCycles函數(shù)調(diào)用
//MarkRoot   ScanRoots  CollectRoots 來回收
CollectCycles(){
    MarkRoot();
    ScanToots();
    ColletRoots();
}



//todo


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容