我是
方圓
,簡單入入JVM的門兒
文章目錄
1. GC的作用範圍
2. 四種GC算法
引用計數算法
對象創建的時候,就給對象綁定一個計數器。每當有一個引用指向該對象時,計數器加一;每當有引用消除時,計數器減一。在沒有引用,即計數器爲0時,這個對象被垃圾回收。(JVM的實現不採用這種算法
)
優點
:比較簡單;缺點
:無法解決對象循環引用的問題;需要佔用額外空間
複製算法
該算法應用於兩個倖存區中。每次只佔用
其中一個倖存區,每進行一次MinorGC,將存活下來的對象複製到另一個空的倖存區(to)中,然後之前的倖存區被清空,稱爲to,而另一個由空變爲非空,稱爲From
優點
:不產生內存碎片缺點
:有一部分內存浪費(to區)
標記清除算法
這個算法分爲如下兩個階段,標記階段
:遍歷所有的GC Roots,並將所有的存活對象進行標記(這裏簡單說一下可達性分析算法
,只有對象可達的纔會被標記);清除階段
:將遍歷堆中所有的對象,將沒有被標記的對象清除。
優點
:相比於引用計數算法,開銷更小缺點
:算法複雜度較高,效率比較低;沒有移動對象,這種方式清理出的內存不是連續的(碎片化
)
標記整理算法
標記整理算法是標記清除算法的改進版,適用於老年代
的垃圾回收。它們在標記階段做的工作是相同的
,只不過在第二個階段,該算法並沒有直接對死亡的對象進行清理,而是對所有存活的對象進行整理
,放到一處存儲空間,然後再把剩下的死亡對象全部清除。
標記
:從根集合進行掃描,對存活的對象進行標記
清除
:移動所有存活的對象,並且按照內存地址次序依次排列,然後將末端內存地址以後的內存全部回收
優點
:不產生碎片空間,解決了標記清除算法碎片化的問題缺點
:若存活的對象很多,則效率很低
3. 什麼對象會晉升到老年代?
- 默認情況經歷15次Minor GC依然存活的對象
- Surivor區中存放不下的對象
- 新生成的
大
對象(-XX:PretenuerSizeThreshold 這個參數可以調節對象大小的閾值,超過這個閾值則會被放在老年代)
4. 常用的調優參數
-XX: SurvivorRatio
Eden和Survivor的比值,默認8:1-XX:NewRatio
老年代和年輕代內存大小的比值,默認2:1-XX:MaxTenuringThreshold
對象從年輕代晉升到老年代,經過的GC次數的閾值-XX:+PretenuerSizeThreshold
大對象直接放入老年代文件大小的閾值
5. 觸發Full GC的條件
老年代空間不足
調用System.gc();
永久代空間不足(JDK1.7及之前)
- CMS GC時出現 promotion failed,concurrent mode failure
- Minor GC 晉升到老年代的平均大小大於老年代剩餘空間
- 使用RMI來進行RPC或管理的JDK應用,每小時執行1次Full GC
6. Stop-the-world 和 Safepoint
Stop-the-world
JVM進行任何GC都會停止應用程序的執行,多數GC的優化就是減少了Stop-the-world來提高性能
Safepoint
安全點是對象引用關係不會發生變化的點,產生安全點的地方,方法調用;循環跳轉;異常跳轉等,線程停頓就需要停在安全點處
7. JVM的運行模式
- Server:啓動慢,運行快(重量級虛擬機)
- Client:啓動快,運行慢(輕量級虛擬機,可用java -version命令查看)
8. 常見的垃圾收集器
8.1 年輕代常見的垃圾收集器
Serial收集器(-XX:+UseSerialGC,複製算法)
單線程垃圾收集,必須暫停所有的工作線程
簡單高效,Client模式下默認使用的年輕代收集器ParNew收集器(-XX:+UseParNewGC,複製算法)
多線程收集,其餘的行爲和Serial收集器一樣
單核執行效率不如Serial收集器,在多核下優勢明顯Parallel Scavenge收集器(-XX:+UseParallelGC,複製算法)
更關注吞吐量,適合用於後臺服務,更好的利用CPU,而不適合用於交互(吞吐量=執行代碼的時間/(執行代碼的時間 + 垃圾回收的時間)
在多核情況下優勢明顯,是Server默認使用的年輕代收集器
8.2 老年代常見的垃圾收集器
Serial Old收集器(-XX:+UseSerialOldGC,標記-整理算法)
單線程垃圾收集,必須暫停所有的工作線程
簡單高效,Client模式下默認老年代收集器Parallel Old收集器(-XX:+UseParallelOldGC,標記-整理算法)
多線程下,吞吐量優先CMS收集器(-XX:+UseConcMarkSweepGC,標記-清除算法)
很屌的收集器,幾乎能與工作線程同時進行,減少了Stop-the-world的時間
8.3 年輕代和老年代都能用的收集器
GarbageFirst收集器(-XX:+UseG1GC,複製算法+標記整理算法)
特點
:並行和併發;分代收集;可預測的停頓;空間整合工作方式
:將整個Java堆內存劃分成多個大小相同的Region,年輕代和老年代不再物理隔離