java垃圾回收回收的是什么
對無用對象的回收 清理掉 騰出他所占用的內(nèi)存空間
JVM的內(nèi)存區(qū)域
- 程序計數(shù)器
占用很少的內(nèi)存 字節(jié)碼的行號指示器 每個線程一個 不會出現(xiàn)內(nèi)存泄露
- java虛擬機(jī)棧
每個線程有一個執(zhí)行的棧 一個方法就是一個棧幀 通過進(jìn)棧出棧來執(zhí)行方法 包括 局部變量表 方法出口 動態(tài)鏈接 操作數(shù)棧
會出現(xiàn)stackoverflow的異常(棧幀太多超過了jvm允許的棧的深度) 申請棧的深度時候 如果沒有足夠的內(nèi)存 會出現(xiàn)OOM
- 本地方法棧
與虛擬機(jī)棧類似 也是線程私有的
- java堆
共享內(nèi)存區(qū)域 存放的是對像實例
- 方法區(qū)
類信息 常量 靜態(tài)變量 等
運行時常量池 運行期間產(chǎn)生的常量會放到運行時常量池中 常量池中無法申請到內(nèi)存時 OOM 測試方法 string.intern
java GC 主要回收的是java堆中 和 方法區(qū)中死去的對象
如何判斷一個對象是否已經(jīng)死了 通過判斷對象是否被引用 通過GC算法來計算是否還有引用
GC 算法
1.引用計數(shù)器算法
如果一個對象被引用了 計數(shù)器+1 如果不再引用了 計數(shù)器-1
優(yōu)點 方便實現(xiàn) 易于理解 判定效率高
缺點 無法解決循環(huán)引用的問題 下邊這段代碼他就回收不了了
class CountingGC{
public Object instance;
public void test(){
CountingGC gcA = new CountingGC();
CountingGC gcB = new CountingGC();
gcA.instatnce = gcB;
gcB.instatnce = gcA;
}
}
2.可達(dá)性分析算法(java 中使用的)
通過GCRoots 向下查找引用鏈 如果一個對象有被引用的對象 但是沒有連接到GCRoots 那么也屬于 不可達(dá)狀態(tài) 當(dāng)jvm進(jìn)行GC的時候會把這部分進(jìn)行標(biāo)記清理 下面之后會補(bǔ)上一張圖
java中的引用
- 強(qiáng)引用 Object A = new Object() 只要引用在垃圾收集器 就不會對其回收
-軟引用 Soft Reference 只要有軟引用就不會對其進(jìn)行回收 知道將要發(fā)生內(nèi)存溢出的時候 會列進(jìn)回收范圍進(jìn)行第二次回收 - 弱引用 Weak Reference 只能生存到下一次
- 虛引用 Phantom Reference 不影響對象的生存時間 但是對象被回收的時候有一個系統(tǒng)通知
finalize 低優(yōu)先級別的Finallizer線程來觸發(fā)他 他是被虛擬機(jī)調(diào)用的 覆蓋這個方法 把this賦值給別的變量 可以逃脫 只能救自己一次 在回收的時候 如果這個對象還在被回收之列 那么這個方法不會在被執(zhí)行了
垃圾收集算法
- 標(biāo)記-清理
標(biāo)記一遍所有被清除的對像 清理一遍
效率低 碎片華 清理后的空間不連續(xù) 如果有大對象進(jìn)來無法分配內(nèi)存 還得在進(jìn)行一次垃圾收集
- 復(fù)制
將空間分成A B兩部分 收集的時候?qū)⒖蛇_(dá)的對象放到B 然后把原來放對象的A清理
缺點是 能使用的內(nèi)存空間占了一半
商業(yè)虛擬機(jī)用這種算法來處理新生代
- 一塊伊甸區(qū) 兩塊幸存區(qū) 比例8:1
因為新生代的對象大多數(shù)朝生夕死 所以使用區(qū)大一些 放活得對象的區(qū)域小一些
創(chuàng)建對象的時候放到伊甸區(qū)和一個幸存區(qū) 回收時把活得放到另一個幸存區(qū) 如果伊甸區(qū)活下來的對象很多大于另一個幸存區(qū) 還可以拿老年代的區(qū)域做候補(bǔ) 老年代相當(dāng)于是擔(dān)保功能
- 標(biāo)記-整理
標(biāo)記一遍所有被清除的對像 活的對象向一端移動 記住邊界 把邊界外的直接清理
老年代使用這個算法
- 老年代的對象存活周期長 如果用復(fù)制法 那每次要復(fù)制的對象就很多 效率低
- 老年代沒有擔(dān)保區(qū)了 如果分成兩個區(qū)另一個保存活對象的區(qū)空間不夠了 沒有內(nèi)存做分配擔(dān)保
- 分代收集
新生代 老生代
收集器
- Serial
特點 暫停其他所有線程 一個單線程進(jìn)行垃圾收集
- Parnew
Serial 多線程版本
- Parallel Scavenge 吞吐量優(yōu)先收集器
- CMS
低停頓 由于收集階段對CPU資源占用多 所以會使程序變慢
- G1