JVM中的垃圾收集器


垃圾收集器

新生代收集器:Serial收集器、ParNew收集器、Parallel Scavenge收集器java

1,Serial收集器
	概念:Serial收集器是一个单线程的收集器,它在进行垃圾收集的时候,必须暂停其余全部的工做线程,直到它搜集结束。(Stop the world)
	优势:简单而高效(与其它单线存放收集器相比)
	应用:运行在Client模式下的虚拟机的默认新生代收集器。
		说明:在桌面应用中,分配给虚拟机管理的内存通常不会很大,收集几十兆或者几百兆的新生代,停顿的时间还不到一秒,只要不是频繁发生,这点停顿仍是能够接受的。
	
2,ParNew收集器
	概念:ParNew收集器其实就是Serial收集器的(并行)多线程版本,即它是使用多线程进行垃圾收集的(多条垃圾收集线程并行工做)。
	优势:能与CMS收集器搭配工做。
	应用:运行在Server模式下的虚拟机的新生代收集器。
		说明:目前只有ParNew能够与CMS收集器搭配使用
			
3,Parallel Scavenge收集器:吞吐量优先收集器
	概念:Parallel Scavenge收集器是一个新生代收集器,
	特色:Parallel Scavenge收集器目标是:达到一个可控制的吞吐量(Throughput)
		说明:吞吐量 = 运行代码的时间 / (运行代码的时间 + 垃圾收集的时间)
		重要:
			1)停顿的时间越少,就越适合与用户交互的程序,良好的响应速度能提高用户体验
			2)吞吐量越高,CPU的利用率就越高,能够尽快的完成程序的运算任务,主要适合在后台运算而不须要太多交互的任务。
			3)GC停顿的时间是以牺牲吞吐量和新生代的空间来换取的。

老年代收集器:Serial Old收集器、Parallel Old收集器、CMS收集器算法

1,Serial Old收集器
	概念:Serial Old收集器是Serial收集器的老年代版本,它一样是一个单线程收集器。使用标记-整理算法。
	应用:
		1)在Client模式下的虚拟机使用
		2)在Server模式下:
			2.1 与Parallel Scavenge收集器搭配使用
			2.2 做为CMS收集器的后备预案,在并发收集失败(Concurrent Mode Failure)时使用。

2,Parallel Old收集器
	概念:Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程和标记-整理算法。
	说明:从jdk1.6开始提供
	重要:在注重吞吐量或者对CPU资源敏感的场合,都优先考虑Parallel Scavenge + Parallel Old 组合。

3,CMS(Concurrent Mark Sweep)收集器
	概念:CMS收集器是一种以获取最短回收停顿为目标的收集器。使用标记-清除算法。
	应用:B/S系统的服务器端上

    过程:  
        1)初始标记(CMS-initial-mark):只扫描老年代中 离root对象最近 的对象并做标记,故初始标记期间虽然须要Stop the word,可是暂停的时间很短。如图一:  
              
        2)并发标记(CMS-concurrent-mark):
			1>在初始标记的基础上(沿着引用链)继续向下追溯标记(RootsTracing)。如图二:
			2>并发标记的线程和应用程序线程是并发执行的,故在并发标记期间,可能会有新的对象进入到老年代(新生代的对象晋升到老年代、在老年代中直接分配对象等形成的),从而致使新进入到老年代中的对象没有被标记。
			
        3)并发预清理(CMS-concurrent-preclean):扫描在并发标记期间新进入老年代的对象,目的是为了减小(下一阶段)从新标记中的工做,由于从新标记期间会Strop the word。
          
        4)从新标记(CMS-remark):从新标记在并发标记期间遗漏的对象。  
            1>须要Stop the word,停顿时间通常会比初始标记阶段的停顿时间稍长一些,但远比并发标记的时间短。  
            2>能够并行remark,减小暂停的时间。(开关参数 -XX:+CMSParallelRemarkEnabled)  
            3>若是remark的时间仍是比较长的话,可使用开关参数 -XX:+CMSScavengeBeforeRemark,强制JVM在remark前进行一次minor gc,这样在必定程度上下降了CMS从新标记阶段对“遗漏”对象的扫描时间。  
              
        5)并发清除(CMS-concurrent-sweep):清理垃圾对象,并发清除线程和应用程序线程是并发执行的。
          
        6)并发重设(CMS-concurrent-reset):对标记的表作清零处理,而且重置CMS收集器的其余数据结构,等待下一次垃圾回收,并发重设线程和应用程序线程是并发执行的。

    说明:
		1)因为GC线程在耗时最长的并发标记阶段、并发清除阶段、并发重设阶段都是与用户线程一块儿工做的,因此从整体上来讲,CMS收集器的gc线程是与用户线程并发执行的。
		2)若是CMS运行期间预留的内存没法知足程序须要,那么就会出现一次“Concurrent Mode Failure”失败,此时JVM将启动后备预案:
			1>临时启用Serial Old收集器,从新对老年代进行gc,这样一来,停顿时间就会很长。
			2>-XX:CMSInitiatingPermOccupancyFraction参数设置的过高就很容易致使Concurrent Mode Failure,从而致使性能降低。

JVM的Server模式与client模式启动:

区别:client模式启动较快,Server模式启动较慢,可是JVM一旦运行起来后,Server模式下JVM的性能将会有很大的提高。
说明:
	1)虚拟机以client模式运行时,使用的是一个代号为C1的轻量级编译器,以server模式运行时JVM使用的是一个相对重量级的编译器(代号为C2)。
	2)C2编译器比C1编译器编译的更完全,故运行时JVM的性能更高。
	3)可使用java -version 命令来查看JVM是client模式仍是server模式。
	4)两种模式的切换能够经过更改配置(jvm.cfg配置文件)来实现:
		32位:JAVA_HOME/jre/lib/i386/jvm.cfg 
			切换:交换 -server KNOWN 与 -client KNOWN 的前后顺序便可。(前提是JAVA_HOME/jre/bin目录下同时存在server与client两个文件夹,分别对应着各自的jvm)
			
		64位:JAVA_HOME/jre/lib/amd64/jvm.cfg 目前64位只支持server模式
			64位jdk1.8中jvm.cfg文件:
				-server KNOWN
				-client IGNORE

图一 图二

相关文章
相关标签/搜索