垃圾回收算法
JVM的垃圾回收算法并不是引用計數(shù)法,而是可達性分析算法
可達性分析算法: 在判斷一個對象是否可以被GC的時候,JVM通過深度優(yōu)先搜索判斷當前對象的應用是否可以到達GC ROOT,如果沒有,則下一次GC時,這個對象會被回收
-
在Java 中GC ROOT可能的類型包括
- 虛擬機棧的引用
- 方法去中類靜態(tài)屬性的引用
- 方法區(qū)中常量的引用
- 本地方法棧中JNI的引用
-
四種引用類型
- 強引用(default):即使OOM也不會被回收
- 軟引用: OOM前會被回收
- 弱引用: 在下一次GC時,會被回收
- 虛引用: 為一個對象設置虛幻引用的唯一作用是,這個對象在被回收時,收到一個系統(tǒng)通知
方法區(qū)中對象的回收
- 常量池中的對象,例如一個字符串“abc”,如果一個沒有String對象引用它,也沒有其他地方引用,如果有必要的話,這個字符串會被回收掉
- 對于類的回收,需要滿足三個條件
- 該類的所有實例已經(jīng)被回收
- 加載該類的所有classloader已經(jīng)被回收
- 該類對應的java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法
在大量使用反射,動態(tài)代理,CGLIB等ByteCode框架的以及OSGI的,需要在方法區(qū)進行垃圾回收
垃圾回收算法
標記-清除
- 效率問題
- 標記清楚以后會產(chǎn)生大量的不連續(xù)的內(nèi)存碎片
復制算法
它將內(nèi)存空間分為兩部分,每次只使用其中的一部分,這部分內(nèi)存使用完了以后,將還存活的對象復制到另一塊內(nèi)存模塊上
- 非常適用于新生代的GC算法
- 具體實現(xiàn): 一塊Eden區(qū),兩塊survivor區(qū)
標記-整理算法
類似標記-清除算法,先是對可回收的對象進行標記,然后這些對象的內(nèi)存向一邊進行移動,然后后整塊清除
- 此回收算法適用于老年代
垃圾回收器
- 目前所有的新生代gc都是需要STW的(Stop the world)
- Serial:單線程STW,復制算法
- ParNew:多線程并行STW,復制算法
- Parallel Scavange:多線程并行STW,吞吐量優(yōu)先,復制算法
- G1:多線程并發(fā),可以精確控制STW時間,整理算法
- 對象優(yōu)先在Eden區(qū)分配存儲空間,當Eden區(qū)內(nèi)存不足時,將會發(fā)起一場Minor GC
- 大對象直接進入老年代 : 盡量少產(chǎn)生一些短命的大對象
- 長期存活的對象直接進入老年代