標記清除演算法, 描述起來很簡單, 從名字上就能看出, 分為兩個階段:
標記階段: 遍歷所有物件, 將活動物件都打上標記
清除階段: 遍歷堆, 將沒有標記的物件釋放掉.
介紹完畢, 本文結束. 開玩笑, 確實看上去很簡單啦. 那就具體思考一下實現吧.
介紹寫的很清楚了, 實現也是兩個階段唄, 先打tag, 後清除.
標記
尋找所有的活動物件, 要從乙個起點開始, 根集合(包括棧、常量池等等), 然後一層一層找下去. 簡單來說就像這樣:
add_mark(obj)
}
將根基合的所有物件都呼叫一遍, 標記完成.
清除
標記時遍歷的是活動物件, 清除階段呢? 遍歷堆. 將堆上所有非活動物件清除. 就比如:
當然, 其中的free
函式也不是簡單的將位址**, 而是將其記錄到乙個鍊錶中, 以方便下次申請記憶體. 實現大概如下:
free(p)else
}
這樣, 申請記憶體時遍歷free_head, 找到大小合適的分塊. 若沒有找到, 就動態擴容咯. 這裡其實還有乙個優化的小方向, 開始的時候忘記了. 為了提高查詢記憶體時速度, 可以將空閒鍊錶按照大小進行區分, 這樣, 需要多大的記憶體, 直接到對應的鍊錶中找就行了.
雖然實現寫的很粗糙, 但大致意思有了.
1.記憶體的碎片化
從上面可以看到, 只對記憶體進行了清除, 但是沒有整理. 而記憶體的申請有事動態的, 就會導致出現很多離散的小片空閒記憶體. 極端情況甚至可能記憶體中還有200mb的空閒記憶體, 但是申請個10kb的空間卻找不到.
2.暫停時間長
其暫停時間與堆的大小成正比, 堆越大, 遍歷清除耗費的時間就越久.
為了解決標記清除演算法的問題, 衍生出了位圖標記法
,bibop法
,延遲清除演算法
等等個人感覺很雞肋(好吧, 或許是我未得其精髓).
為了解決標記清除的問題, 有衍生出了標記複製
,標記整理
演算法, 之後再議.
GC演算法 筆記 GC標記 壓縮演算法
將 gc標記 清除演算法與gc複製演算法相結合。一 lisp2演算法 標記階段結束後進入壓縮階段,壓縮階段縮小被標記節點之間的距離。compaction phase set forwarding ptr adjust ptr move obj 優點 可有效利用堆 缺點 壓縮花費計算成本 二 two ...
GC演算法 複製演算法
複製演算法就是將記憶體空間二等分,每次只使用其中一塊.當執行gc時,講a部分的所有活動物件集體移到b中,就可以講a全部釋放.畫個圖就是 在執行gc前,記憶體長這樣 當執行gc後,記憶體就變成這樣了 還記得標記清除演算法的問題是什麼嗎?記憶體碎片化嚴重.現在好了,碎片化問題解決了,每次gc執行後,記憶...
GC複製演算法
gc複製演算法 它是把某一空間的活動物件全部複製到另乙個空間,複製完成後gc也就結束了 一起看下gc複製演算法的copying函式 copying copy函式在複製時會先檢查是否已被複製,若已被複製,不再操作,否則進行複製,貼上copied標籤複製完成返回新空間的位址,這樣即使有多個物件引用obj...