深入理解java虚拟机-2 垃圾收集器

时间:2022-12-27 20:59:11

1.对象已死?

1.引用计数算法
2.可达性分析算法

2.引用

1.强引用

2.软引用
3.弱引用
4.虚引用
作用:在这个对象被回收时,收到一个系统通知

3.Finalize

一个对象死亡的过程

发现没有和GC Roots相连接->被标记一个,并检测,是否有必要执行Finalize方法->Yes的话被放入F-Queue中
->稍后GC对 F-Queue队列进行标记->对象如果在finalize中拯救了自己,他将被移出即将回收队列

这个方法不同于C++析构函数,不建议使用

4.垃圾收集算法

1.标记-清除算法
两个不足:效率问题,标记与清除两个功能效率都不高;空间问题,会产生大量碎片
2.复制算法
简单,高效,代价是牺牲一半的内存
适合新生代
3.标记-整理算法
先进行标记,然后让存活下来的向一边移动,然后清理掉边界外的内存
4.分代收集算法

根据对象存活周期不同,将内存划分为几块,新生代使用2复制算法。老年代使用标记清除或标记整理算法

5.HotSpot算法实现-虚拟机如何发起内存回收

1.枚举根节点

枚举根节点时必须保证分析过程中对象的引用关系没有变化。枚举根节点时,虚拟机一定会停顿。

主流虚拟机使用精确式GC,HotSpot中使用OopMap的数据结构来定位对象引用。

2.安全点

Hotspot会在特定位置记录了对象引用到OopMap,这个位置就是安全点。

安全点选定问题:

如何让所有线程都跑到“安全点停下来那?

1.抢占式中断

先把所有线程都中断,然后让没有在安全点的,恢复线程,让他跑到安全点(这种方法几乎没有人使用了)

2.主动式中断”

不直接操作线程,仅设置一个标志,这个标志与安全点重合,执行到安全点就完成线程中断


3.安全区域

安全区域:是引用关系不会发生变化的一段代码片段,这个区域里面任何地方GC都是安全的。

6.HotSpot算法实现-垃圾收集器

前面三个都是新生代收集器,使用的都是复制算法

1.Serial收集器

单线程收集器,运行在Client模式下面的默认新生代收集器。 特点:简单且高效;对于单个CPU的情况下,没有线程直接的交互,效率更高。

2.PerNew收集器

PeriNew 是Serial的多线程版本,一个并行的多线程收集器。是很多在Server下面首选的新生代收集器,与性能无关的原因是:目前只有他能与CMS收集器配合工作。

3.Parallel Scavenge收集器

特点:

1,吞吐量优先收集器
2,于PeiNew区别是,这个收集器采用自适应调节策略
这个收集器的目的是达到一个可控制的吞吐量。吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
参数详解:
1,-XX:MaxGCPauseMillis

设置内存回收不超过的时间,GC停顿时间缩短是以牺牲性能和新生代空间来保证的。

2,-XX:GCTimeRadtio

设置垃圾收集时间所占比重。(0<n<100)

3.-XX:UserAdaptiveSizePolicy

只需设置好基本的内存数据,然后剩下的交给虚拟机自动完成


4,Serial Old收集器

标记整理算法 单线程收集器,和Serial一样用于Client模式下老年代收集。 两大用途: 在jdk1.5以及之前与Parallel Old收集器搭配使用 CMS收集器后备方案

5,Parallel Old收集器

标记整理算法

Parallel Scavenge老年化版本,

在注重吞吐量和CPU资源敏感的地方使用 Parallel Scavenge 和Parallel Old 组合

6,CMS收集器

并发低停顿收集器 标记-清除算法 CMS收集器的目的是获取最短回收停顿时间。CMS适合 互联网站和B/S系统服务器端,这种要求响应时间的 步骤: 1.初始标记 需要stop the world,标记GC Root能关联到的对象 2,并发标记 从GC Roots 对对象进行可到达性分析,找出存活的对象 3,重新标记 需要stop the world,修正并发期间变动的那部分对象的标记记录 4,并发清除 花费时间最长的并发标记与并发清除是可以并行的, CMS的缺点: 1.对CPU资源比较敏感,CPU不足4个时,CMS对客户程序影响较大 2.无法处理浮动垃圾,就是在并发清除过程中产生的垃圾,CMS无法再当次处理中收集他们 而且,由于CMS是并发的收集器所以不能等到老年代几乎快满了再收集,默认68%, -XX:CMSInitiatingOccupancyFraction 用来提高触发百分比 如果运行期间,预留的内存空间无法满足CMS收集垃圾,就会启动备用方案,Serial Old收集器.所以-XX:CMSInitiatingOccupancyFraction设置太高反而性能降低 3.基于标记-清除,会有大量碎片产生 -XX:UseCMSCompactAtFullCollection 开关参数,模式是开启,用于开启内存碎片这个能力过程 -XX:CMSFUllGCsBeforeCompaction 多少次不执行压缩的FullGC后,来一次带压缩的

7,G1收集器

面向服务器端应用的垃圾收集器 特点: 1.并行与并发 2.分代收集 3.空间整合,使用标记整理算法,不会产生内存碎片 4.可预测的停顿,不仅追求地停顿,还建立了可预测时间的模型
步骤: 1.初始标记 需要stop the world,标记GC Root能关联到的对象2,并发标记 从GC Roots 对对象进行可到达性分析,找出存活的对象3,最终标记 修正并发期间变动的那部分对象的标记记录4,筛选回收 




JVM 参数
XX:+<option> 启用选项 -XX:-<option> 不启用选项 -XX:<option>=<number>  -XX:<option>=<string>

 

附录:参数描述

-XX:+UseSerialGC

Jvm运行在Client模式下的默认值,打开此开关后,使用Serial + Serial Old的收集器组合进行内存回收
-XX:+UseParNewGC 打开此开关后,使用ParNew + Serial Old的收集器进行垃圾回收
-XX:+UseConcMarkSweepGC 使用ParNew + CMS +  Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现“Concurrent Mode Failure”失败后的后备收集器使用。
-XX:+UseParallelGC Jvm运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge +  Serial Old的收集器组合进行回收
-XX:+UseParallelOldGC 使用Parallel Scavenge +  Parallel Old的收集器组合进行回收
-XX:SurvivorRatio 新生代中Eden区域与Survivor区域的容量比值,默认为8,代表Eden:Subrvivor = 8:1
-XX:PretenureSizeThreshold 直接晋升到老年代对象的大小,设置这个参数后,大于这个参数的对象将直接在老年代分配
-XX:MaxTenuringThreshold 晋升到老年代的对象年龄,每次Minor GC之后,年龄就加1,当超过这个参数的值时进入老年代
-XX:UseAdaptiveSizePolicy 动态调整java堆中各个区域的大小以及进入老年代的年龄
-XX:+HandlePromotionFailure 是否允许新生代收集担保,进行一次minor gc后, 另一块Survivor空间不足时,将直接会在老年代中保留
-XX:ParallelGCThreads 设置并行GC进行内存回收的线程数
-XX:GCTimeRatio GC时间占总时间的比列,默认值为99,即允许1%的GC时间,仅在使用Parallel Scavenge 收集器时有效
-XX:MaxGCPauseMillis 设置GC的最大停顿时间,在Parallel Scavenge 收集器下有效
-XX:CMSInitiatingOccupancyFraction 设置CMS收集器在老年代空间被使用多少后出发垃圾收集,默认值为68%,仅在CMS收集器时有效,-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSCompactAtFullCollection
由于CMS收集器会产生碎片,此参数设置在垃圾收集器后是否需要一次内存碎片整理过程,仅在CMS收集器时有效
-XX:+CMSFullGCBeforeCompaction
设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与UseCMSCompactAtFullCollection参数一起使用
-XX:+UseFastAccessorMethods
原始类型优化
-XX:+DisableExplicitGC
是否关闭手动System.gc
-XX:+CMSParallelRemarkEnabled
降低标记停顿
-XX:LargePageSizeInBytes
内存页的大小不可设置过大,会影响Perm的大小,-XX:LargePageSizeInBytes=128m

 

Client、Server模式默认GC

 

  新生代GC方式老年代和持久GC方式

Client

Serial 串行GC Serial Old 串行GC
Server Parallel Scavenge  并行回收GC Parallel Old 并行GC

Sun/oracle JDK GC组合方式

 

  新生代GC方式老年代和持久GC方式

-XX:+UseSerialGC

Serial 串行GC Serial Old 串行GC
-XX:+UseParallelGC Parallel Scavenge  并行回收GC Parallel Old 并行GC
-XX:+UseConcMarkSweepGC ParNew 并行GC CMS 并发GC 
当出现“Concurrent Mode Failure”时
采用Serial Old 串行GC
-XX:+UseParNewGC ParNew 并行GC Serial Old 串行GC
-XX:+UseParallelOldGC Parallel Scavenge  并行回收GC Parallel Old 并行GC
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
Serial 串行GC CMS 并发GC 
当出现“Concurrent Mode Failure”时
采用Serial Old 串行GC


参数部分参考自:http://blog.csdn.net/huxian1234/article/details/17163023