從本文開始,將持續更新GC算法,GC算法是面試java必問的知識,同時,在c,c++這種需要手動GC的語言,更是需要掌握的算法,一起加油吧!
本篇是接下來算法的前置知識,畢竟搞懂算法邏輯的基礎,是搞懂概念
結構
對象
組成:
- 頭:保存對象的一些基本信息,比如大小,種類等,他的地址也代表對象的地址,類似於數組的首地址
- 域:對象中可以訪問的部分,裏面可以有各種數據,也可以有指向其他對象的指針(指向其他對象的頭)
分類
- 活動對象:能被mutator引用的對象(後面會講),可以理解爲能被引用的對象
- 非活動對象:不能被mutator引用的對象,這種對象就是將被GC的對象,稱爲垃圾
mutator
這是一種動作,作用是改變GC中對象的引用關係,可以類比爲new操作,new就是新建一個對象,mutator可以申請內存,爲new對象做準備,也可以修改對象的域中指針的方向
其他結構
- 堆:執行程序時存放對象的空間
- 根:指向對象的指針的起點
- 分塊:當mutator時,從堆中分出去的一塊內存
- 分配:從堆中選出一個分塊給mutator的方法
算法評價
如何判定一個GC算法是好的呢?有以下幾個方面
-
吞吐量throughput:單位時間內的處理能力
計算方法是:heap_size/GC的時間
比如
上圖中的throughput=堆的大小/(A+B+C),A,B,C爲三次GC -
最大暫停時間:因GC而暫停mutator的最大時間
從上圖看出,當GC觸發時,mutator將會暫停,所以也可以理解爲單次GC所需要的最大時間,圖中B最長,所以最大暫停時間是B -
堆使用效率
有兩方面,
一是對象的頭,對象中,頭越大,信息越多,越方便找到他,但是效率會降低,因爲頭大了,對象大小不變的話,所能生成的對象數量就會減少二是利用率,如果算法越好,對堆的利用率越高當然好,但是相應的GC會越困難,類比hash算法雖然可以通過映射使得數組空間得以最大利用,但是因此數組排列很不規律。在堆中也是一樣,類似的對象或許分佈堆中各地,很難去全部找出
-
訪問局部性
某些對象由於有較強相關性,會一起生成,一起毀滅,比如有boyfriend就會有girlfriend,這類對象最好放在相近的地方,好生成,好清除
所以,我們的GC算法追求的是較大的吞吐量,較小的最大暫停時間,合適的利用率,以及最大限度的局部性
現在你已經掌握的學習GC的所有前置知識啦,一起來學習GC算法吧