GC的標記算法
-
引用計數算法
-
通過判斷對象的引用數量來決定對象是否可以被回收
-
每個對象實例都有一個引用計數器,被引用則+1,完成引用則-1
-
任何引用計數為0的對象實例可以被當作垃圾收集
優點:執行效率高,程序執行受影響較小
缺點:無法檢測出循環引用的情況,導致內存泄漏
-
-
可達性分析算法(主流)
- 通過判斷對象的引用鏈是否可達來決定對象是否可以被回收

- 可以作為GC Root的對象
- 虛擬機棧中引用的對象(棧幀中的本地變量表)
- 方法區中的常量引用對象
- 方法區中的類靜態屬性引用的對象
- 本地方法棧中JNI(Native方法)的引用對象
- 活躍線程的引用對象
GC的垃圾回收算法
-
標記-清除算法(Mark and Sweep)(適合垃圾少)
- 標記:從根集合進行掃描,對存活的對象進行標記(可達性分析算法)
- 清除:對堆內存從頭到尾進行線性遍歷,回收不可達對象內存

-
標記-整理算法(Compacting)(適合垃圾少)
- 標記:從根集合進行掃描,對存活的對象進行標記(可達性分析算法)
- 整理:移動所有存活的對象,且按照內存地址次序依次排列,將末端內存地址以后的內存全部回收(對標記-清除算法的優化,防止內存碎片問題)
-
復制算法(Copying)(適合垃圾多,減少復制的對象數量)
- 將內存分為對象面和空閑面
- 對象在對象面創建
- 存活的對象被從對象面復制到空閑面,此時原先的對象面變為現在空閑面,被復制了對象的原先空閑面變為現在對象面
-
分代收集算法(Generational Collector)
-
以上回收算法的組合拳
-
按照對象生命周期的不同划分區域以采用不同的垃圾回收算法
-
年輕代使用復制算法(年輕代,垃圾多適合復制算法),老年代使用標記整理算法或標記清除算法(老年代,垃圾少適合這兩種算法)


-
年輕代使用的算法,也叫Minor GC
-
年輕代的內存分布(Eden區,兩個Surrvivor區(from區,to區))
-

-

-
對象如何晉升到老年代
- 經歷一定Minor次數依然存活的對象
- Survivor區中存放不下的對象
- 新生成的大對象(-XX:+PretenuerSizeThreshold 大於該值直接放進老年代)
-
常用的調優參數
- -XX:SurvivorRatio:Eden和Survivor的比值,默認8:1
- -XX:NewRatio:老年代和年輕代內存大小的比例
- -XX:MaxTenuringThreshold:對象從年輕代晉升到老年代經過GC次數的最大閾值
-
-
老年代使用的算法
- Full GC(新老同時一起GC)和Major GC(老年代GC:標記-整理算法)
- 觸發Full GC的條件
- 老年代空間不足
- 永久代空間不足(jdk8前)
- Minor GC 晉升到老年代的平均大小大於老年代的剩余空間
- 調用System.gc()
-
年輕代常見的垃圾收集器
JVM的運行模式
- Server:啟動慢,重量級,啟動后運行速度快
- Client:啟動快,輕量級,啟動后較Server運行速度慢
Serial收集器
-XX:+UseSerialGC,復制算法
- 單線程收集,進行垃圾收集時,必須暫停所有工作進程
- 簡單高效,Client模式下默認的年輕代收集器

ParNew收集器
-XX:+UseParNewGC,復制算法
- 多線程收集,其余行為、特點和Serial收集器一樣
- 屬於Server模式下的收集器單核執行效率不如Serial,在多核下執行才有優勢

Parallel Scavenge收集器
-XX:+UseParallerel,復制算法
吞吐量=運行代碼的時間/(運行代碼的時間+垃圾收集時間)
- 比起關注用戶線程停頓時間,更關注系統的吞吐量
- 在多核下執行才有優勢,Server模式下默認的年輕代收集器

老年代常見的垃圾收集器
Serial Old收集器
-XX:+UseSerialOldGC,標記-整理算法
-
單線程收集,進行垃圾收集時,必須暫停所有的工作線程
-
簡單高效,Client模式下默認的老年代收集器

Parallel Old收集器
-XX:+UserParallelOldGC,標記-整理算法
- 多線程,吞吐量優先
CMS收集器
-XX:+UseConcMarkSweepGC,標記-清除算法
新老代集成的垃圾回收器
G1收集器
-XX:+UseG1GC,復制+標記-整理算法
垃圾收集器之間的聯系
連線表示可以共用

Java中的引用類型
強引用
- 最普遍的引用:
Object obj=new Object() - 即使拋出OutOfMemoryError(內存滿了)也不會回收具有強引用的對象
- 通過將對象設置為null來弱化引用,使其被回收
軟引用(Soft Reference)
- 對象處在有用但非必須的狀態
- 只有當內存空間不足時,GC會回收該引用的對象的內存
- 可以用來實現高速緩存
- 同樣,軟引用可以和一個引用隊列(
ReferenceQueue)聯合使用,如果軟引用所引用的對象被垃圾回收,Java虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。

弱引用(Weak Reference)
- 非必須的對象,比軟引用更弱一些
- GC時會被回收
- 被回收的概率也不大,因為GC線程優先級比較低
- 同樣,弱引用可以和一個引用隊列(
ReferenceQueue)聯合使用,如果弱引用所引用的對象被垃圾回收,Java虛擬機就會把這個弱引用加入到與之關聯的引用隊列中。

虛引用(PhantomReference)
- 不會決定對象的生命周期
- 任何時候都可能被垃圾收集器回收
- 跟蹤對象被垃圾收集器回收的活動,起哨兵作用
- 必須和引用隊列ReferenceQueue聯合使用

四種引用的關系




