GC是什么?
分代收集算法。次数上频繁收集Young区;次数上较少收集Old区;基本不动Perm区
JVM在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代。因此GC按照回收的区域又分了两种类型,一种是普通的GC(Minor GC),一种是全局的GC(Major GC or Full GC)
普通GC,只针对新生代区域的GC;全局GC针对老年代的GC,偶尔伴随对新生代的GC以及对永久代的GC
[GC [PSYoungGen: 504K->504K(6656K)] 4672K->4696K(19968K), 0.0011182 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 504K->0K(6656K)] [ParOldGen: 4192K->492K(5632K)] 4696K->492K(12288K) [PSPermGen: 2577K->2576K(21504K)], 0.0161250 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
GC算法
1. 复制算法(Copying)
年轻代(也叫新生代、新生区)使用的是Minor GC,这种GC算法采用的是复制算法
2. 标记清除(Mark-Sweep)
老年代一般是由标记清除或标记清除与标记整理的混合实现
3.标记压缩(Mark-Compact),也叫标记真理
4.标记-清除-压缩(Mark-Sweep-Compact)
GC收集器分类
Serial收集器
单线程的收集器,基本不用,不做过多说明
Parnew收集器
多线程的收集器,基本不用,不做过多说明
Parallel Scavenge 收集器
又称为吞吐量优先收集器,和ParNew收集器类似,是一个新生代收集器。使用复制算法的并行多线程收集器。Parallel Scavenge是jdk1.7和jdk1.8默认的收集器,特点是并行的多线程回收,以吞吐量优先
-XX:+PrintCommandLineFlags 可以让在程序运行前打印出用户手动设置或者JVM自动设置的XX选项
重要的参数有三个,其中两个参数用于精确控制吞吐量,分别是:
控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数
MaxGCPauseMillis参数允许的值是一个大于0的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。不过大家不要异想天开地认为如果把这个参数的值设置得稍小一点就能使得系统的垃圾收集速度变得更快,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的:系统把新生代调小一些,收集300MB新生代肯定比收集500MB快吧,这也直接导致垃圾收集发生得更频繁一些,原来10秒收集一次、每次停顿100毫秒,现在变成5秒收集一次、每次停顿70毫秒。停顿时间的确在下降,但吞吐量也降下来了。
直接设置吞吐量大小的 -XX:GCTimeRatio参数。
GCTimeRatio参数的值应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率。如果把此参数设置为19,那允许的最大GC时间就占总时间的5%(即1 /(1+19)),默认值为99,就是允许最大1%(即1 /(1+99))的垃圾收集时间。
UseAdaptiveSizePolicy开关参数。
-XX:+UseAdaptiveSizePolicy是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)。
自适应调节策略
Parallel Scavenge收集器能够配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成。只需要把基本的内存数据设置好(如-Xmx设置最大堆),然后使用-XX:MaxGCPauseMillis参数(更关注最大停顿时间)或GCTimeRatio参数(更关注吞吐量)给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。
[GC[PSYoungGen 表示用的是年轻代使用Parallel Scavenge收集器。
[GC[ParNew 表示使用的是年轻代使用ParNew收集器(Parallel New收集器)。
[GC[DefNew 表示用的是年轻代使用Serial收集器(Serial New收集器)。
[GC[PSOldGen 表示用的是老年代使用的Parallel Old收集器。
Parallel Old参考:是Parallel Scavenge收集器的老年代版本,用于老年代的垃圾回收,但与Parallel Scavenge不同的是,它使用的是“标记-整理/压缩算法”。适用于注重于吞吐量及CPU资源敏感的场合,jdk1.7 和1.8默认使用的老年代收集器,-XX:+UseParallelOldGC
CMS 收集器(Concurrent Mark Sweep)
简单说一下;老年代的收集器,使用标记清除算法,是一个关注系统停顿时间的收集器(重视响应速度,希望系统停顿时间最短);通常与ParNew收集器配合使用;可以指定在老生代用掉多少内存后开始进行垃圾回收。与吞吐量优先的回收器不同的是,吞吐量优先的回收器在老生代内存用尽了以后才开始进行收集。
吞吐量与响应时间
吞吐量是对单位时间内完成的工作量的量度:
每分钟的数据库事务
每秒传送的文件千字节数
每秒读或写的文件千字节数
每分钟的 Web 服务器命中数
以hits/sec或者MB/sec为主
响应时间是提交请求和返回该请求的响应之间使用的时间:
数据库查询花费的时间
将字符回显到终端上花费的时间
访问 Web 页面花费的时间
以s或者ms为主
通常,平均响应时间越短,系统吞吐量越大;平均响应时间越长,系统吞吐量越小;但是,系统吞吐量越大, 未必平均响应时间越短;因为在某些情况(例如,不增加任何硬件配置)吞吐量的增大,有时会把平均响应时间作为牺牲,来换取一段时间处理更多的请求。
因此注重响应速度则使用CMS收集器,注重吞吐量则使用Parallel收集器
G1 收集器 Garbage First
jdk1.9默认使用的GC收集器,jdk1.7以上版本也可使用。可作用于新生代和老年代的GC,用于取代CMS,也是注重停顿时间的收集器,原理类似CMS,比CMS更好。老年代的回收使用了标记清除+标记整理的混合算法。
-XX:+UseG1GC:启用G1垃圾回收器
GC 收集器组合
-XX:+UseSerialGC:在新生代和老年代使用串行收集器
-XX:+UseParallelGC :新生代使用并行回收收集器,更加关注吞吐量
-XX:+UseParallelOldGC:老年代使用并行回收收集器
-XX:ParallelGCThreads:设置用于垃圾回收的线程数
-XX:+UseParNewGC:在新生代使用并行收集器
-XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器
-XX:ParallelCMSThreads:设定CMS的线程数量
-XX:+UseG1GC:启用G1垃圾回收器