jvm中垃圾回收算法
垃圾回收算法
如何判斷是否是垃圾:
沿着GC Root找,如果沒有被GCRoot直接引用,則會判定爲垃圾
- 標記清除發
- 分代整理
- 複製
1.1 標記清除算法
先標記後清除
優點:速度快,垃圾回收速度快
缺點:空間不連續,容易產生內存碎片,會導致內存溢出
1.2標記整理算法
優點:不會產生內存碎片
缺點:由於需要移動對象,如果其他對象引用了,則需要改變引用地址,涉及到內存的區塊的拷貝移動,速度較慢
1.3 複製算法
優點:不會產生內存碎片
缺點:會佔用雙倍的內存空間
- 總結
在JVM中,面對不同的情況會採用上面不同的算法實現垃圾回收
2.1 JVM中垃圾回收機制
分代的垃圾回收機制
新生代:用完了可以丟棄的對象
老年代:長時間使用的對象
- 新生代中可以分爲兩大塊區域:Eden區和兩個Survivor(倖存區)
疑問1:爲什麼要存在Survivor - 如果沒有Survivor,Eden區每進行一次Minor GC,存活的對象就會被送到老年代。老年代很快被填滿,觸發Major GC(因爲Major GC一般伴隨着Minor GC,也可以看做觸發了Full GC)。老年代的內存空間遠大於新生代,進行一次Full GC消耗的時間比Minor GC長得多。
疑問2 :爲什麼要有兩個Survivor - 設置兩個Survivor區最大的好處就是解決了碎片化
2.1.1 垃圾回收機制過程
1.3:在將倖存的對象放進幸存區時,同時執行將倖存對象的壽命+1操作
1.8:當老年代的內存不足,會觸發FullGc
2.2.2 總結
- new的對象首先會被分配到Eden區域
- 新生代空間不足時,觸發Minor gc,將Eden和From中存活的對象使用copy算法複製到to中,存活的對象的年齡+1,並且交換from和to的位置。交換之前清除垃圾
- minor gc執行時會依法stop the word。暫停其他用戶的線程,只存在垃圾回收線程,等垃圾回收結束,用戶線程纔會恢復運行,STW時間短。
- 當對象壽命超過閾值時,就會晉升至老年代,壽命閾值最大是15次(會保存對象的頭中,存壽命的地方是4bit)。
- 當老年代空間不足,會先嚐試觸發minor gc,如果之後空間扔不足,會觸發Full gc。也會觸發stop the word。只不過STW的時間更長
- 爲什麼老年代的回收算法教程
* 新生代採用的複製算法, 老年代,存活對象比較多,清除起來比較慢
* 採用的算法是標記+清除或者標記+標記+整理
- 爲什麼老年代的回收算法教程
2.3 GC分析
2.4 大對象導致OutOfMemory
新生代無法存下,直接晉升老年代
當老年代也無法放下時,會報OutOfMemory
2.5 垃圾回收器
- 串行的垃圾回收器
* 底層是單線程垃圾回收器,
* 使用場景:堆內存較小,適合個人電腦 - 吞吐量優先
* 多線程
* 對內存較大,多核CPU支持
* 讓單位時間內,STW的時間最短 - 響應時間優先
- 多線程
- 對內存較大,多核CPU支持
- 儘可能讓單次STW(暫停其他線程)的時間最短;
吞吐量:垃圾回收時間佔程序運行時間的佔比
2.5.1 串行垃圾回收器
- 開啓的語句:-XX:UseSerialGC =Serial +SerialOld
2.5.2 吞吐量優先的垃圾回收器
2.5.3 響應時間優先垃圾回收器
2.6 Garbage First(G1垃圾回收器)
JDK9中默認的垃圾回收機制,取代 了CMS