java - GC垃圾收集器详解(二)

CMS收集器

CMS收集器(ConcurrentMarkSweep:并发标记清除)是一种以获取最短回收停顿时间为目标的收集器。

适合应用在互联网站或者B/S系统的服务器上,这类应用尤其重视服务器的响应速度,希望系统停顿时间最短。

CMS非常适合堆内存大、CPU核数多的服务器端应用,也是G1出现之前大型应用的首选收集器。

Concurrent Mark Sweep 并发标记清除,并发收集低停顿,并发指的是与用户线程一起执行

开启该收集器的JVM参数:-XX:+UseConcMarkSreepGC,开启该参数后会自动将-XX:+UseParNewGC打开。

开启该参数后,使用ParNew(Young区用)+CMS(Old区用)+SerialOld的收集器组合,SerialOld将作为CMS出错的后备收集器。

当CMS已无力收集垃圾时(内存碎片过多)会使用SerialOld进行FullGc。

CMS进行GC的四个步骤:

  1. 初始标记(CMS initial mark):只是标记一下GC Roots能直接关联的对象,速度很快,仍然需要暂停所有的工作线程
  2. 并发标记(CMS concurrent mark)和用户线程一起:进行GC Roots跟踪的过程,和用户线程一起工作,不需要暂停工作线程。主要标记过程,标记全部对象
  3. 重新标记(CMS remark):为了修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程。由于并发标记时,用户线程仍然运行,因此在正式清理前,再做修正。
  4. 并发清除(CMS concurrent sweep)和用户线程一起:清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。基于标记结果,直接清理对象。

由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户一起并发工作,所以总体上来看CMS收集器的内存回收和用户线程是一起并发地执行。

CMS进行GC的四个步骤图片

CMS优点:并发收集低停顿

CMS缺点:

  1. 并发执行,对cpu资源压力大:由于并发进行,CMS在收集与应用线程会同时会增加对堆内存的占用,也就是说,CMS必须要在老年代堆内存用尽之前完成垃圾回收,否则CMS回收失败时,将触发担保机制,串行老年代收集器将会以
    STW的方式进行上次GC,从而造成较大停顿时间。
  2. 标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩。CMS也提供了参数-XXlCMSFullGCsBeForeCompaction(默认0,即每次都进行内存整理)来指定多少次CMS收集之后,进行一次压缩的Full GC。

如何选择垃圾收集器

  • 单CPU或小内存,单机程序
    -XX:+UseSerialGC
  • 多CPU,需要最大吞吐量,如后台计算型应用
    -XX:+UseParallelGc 或者
    -XX:+UseParallelOlGC
  • 多CPU,追求低停顿时间,需快速响应如互联网应用
    -XX:+UseConcMarkSweepGC
    -XX:+ParNewGC
参数 新生代垃圾收集器 新生代算法 老年代垃圾收集器 老年代算法
-XX:+UseSerialGc SerialGc 复制 SerialOldGc 标整
-XX:+UseParNewGc ParNew 复制 SerialOldGc 标整
-XX:+UseParallelGc/-XX:+UseParallelOldGc Parallel[Scavenge] 复制 ParallelOld 标整
-XX:+UseConcMarkSweepGc ParNew 复制 CMS+SerialOld的收集器组合(SerialOld作为CMS出错的后备收集器) 标清
-XX:+UseG1GC G1整体采用标记-整理算法 局部是通过复制算法,不会产生内存碎片

原文地址:https://www.cnblogs.com/cjunn/p/12233441.html

时间: 2024-10-29 12:35:56

java - GC垃圾收集器详解(二)的相关文章

java - GC垃圾收集器详解(三)

以前收集器的特点 年轻代和老年代是各自独立且连续的内存块 年轻代收集必须使用单个eden+S0+S1进行复制算法 老年代收集扫描整个老年代区域 都是以尽可能少而快速地执行GC为设计原则 G1是什么 G1(Garbage-Frist)收集器,是一款面向服务端应用的收集器 从官网的描述中,我们知道G1是一种服务器端的垃圾收集器,应用在多处理器和大容量内存环境中,在提高吞吐量的同时,尽可能的满足垃圾收集暂停时间的要求.另外,它还具有以下特性: 像CMS收集器一样,能与应用程序线程并发执行 整理空闲空间

深入理解JVM(5)——HotSpot垃圾收集器详解

HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器.根据新生代和老年代各自的特点,我们应该分别为它们选择不同的收集器,以提升垃圾回收效率. 新生代垃圾收集器: Serial垃圾收集器 a)        单线程:只开启一条GC线程进行垃圾回收,并且在垃圾回收过程中停止一切用户线程,从而用户的请求或图形化界面会出现卡顿. b)        适合客户端应用 c)        简单高效:由于Serial收集器只有一条GC线程,因此避免了

Java虚拟机工作原理详解 ( 二 )

首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实例对应了一个独立运行的Java程序,而JVM执行引擎实例则对应了属于用户运行程序的线程:也就是JVM实例是进程级别,而执行引擎是线程级别的. JVM是什么?—JVM的生命周期 JVM实例的诞生:当启动一个Java程序时,一个JVM实例就产生了,任何一个拥有 publicstaticvoidmain(String[]args)函数的class都可以作为JVM实例运行的起点,既然如此,那么JVM如何知道 是运行classA的main而不是

Java内存模型(JMM)详解

在Java JVM系列文章中有朋友问为什么要JVM,Java虚拟机不是已经帮我们处理好了么?同样,学习Java内存模型也有同样的问题,为什么要学习Java内存模型.它们的答案是一致的:能够让我们更好的理解底层原理,写出更高效的代码. 就Java内存模型而言,它是深入了解Java并发编程的先决条件.对于后续多线程中的线程安全.同步异步处理等更是大有裨益. 硬件内存架构 在学习Java内存模型之前,先了解一下计算机硬件内存模型.我们多知道处理器与计算机存储设备运算速度有几个数量级的差别.总不能让处理

Java虚拟机工作原理详解

原文地址:http://blog.csdn.net/bingduanlbd/article/details/8363734 一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 [java] view plaincopy javac YourClassName.java 此时,你的java代码就被编译成字节码(.class).如果你是在Eclipse IDE或者其他开发工具中,你保存代码

Java虚拟机垃圾收集器与内存分配策略

Java虚拟机垃圾收集器与内存分配策略 概述 那些内存需要回收,什么时候回收,如何回收是GC需要完成的3件事情. 程序计数器,虚拟机栈与本地方法栈这三个区域都是线程私有的,内存的分配与回收都具有确定性,内存随着方法结束或者线程结束就回收了. java堆与方法区在运行期才知道创建那些对象,这部分内存分配是动态的,本章笔记中分配与回收的内存指的就是:java堆与方法区. 判断对象已经死了 引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它,计数器+1;引用失败,计数器-1.计数器为0则改判

深入JVM虚拟机(四) Java GC收集器

深入JVM虚拟机(四) Java GC收集器 1 GC收集器 1.1 Serial串行收集器 串行收集器主要有两个特点:第一,它仅仅使用单线程进行垃圾回收:第二,它独占式的垃圾回收. 在串行收集器进行垃圾回收时,Java 应用程序中的线程都需要暂停("StopThe World"),等待垃圾回收的完成,这样给用户体验造成较差效果.虽然如此,串行收集器却是一个成熟.经过长时间生产环境考验的极为高效的收集器.新生代串行处理器使用复制算法,实现相对简单,逻辑处理特别高效,且没有线程切换的开销

java classLoader体系结构使用详解

原创整理不易,转载请注明出处:java classLoader体系结构使用详解 代码下载地址:http://www.zuidaima.com/share/1774052029516800.htm jvm classLoader architecture: Bootstrap ClassLoader/启动类加载器 主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作. Extension ClassLoader/扩展类加载器  主要负

java.util.Scanner应用详解++扫描控制台输入

java.util.Scanner应用详解 java.util.Scanner是Java5的新特征,主要功能是简化文本扫描.这个类最实用的地方表现在获取控制台输入,其他的功能都很鸡肋,尽管Java API文档中列举了大量的API方法,但是都不怎么地. 一.扫描控制台输入 这个例子是常常会用到,但是如果没有Scanner,你写写就知道多难受了. 当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫