首页 > 其他 > 详细

jvm垃圾收集器

时间:2019-07-20 17:43:22      阅读:289      评论:0      收藏:0      [点我收藏+]

垃圾收集算法

  • 垃圾收集器和垃圾回收算法的关系?
    垃圾算法(引用计数,复制算法,标记清除,标记整理)都是内存回收的方法论,垃圾收集器是这种算法的落地实现。

  • 请移步JVM中的GC收集算法有哪些

先了解相关概念

垃圾收集器主要发生的区域

主要发生在方法区和堆中,其中方法区在jdk1.8中的实现是元空间(Metaspace)

次收集器

发生在新生代中的GC,被称为Young GC(Scavenge GC,Minor GC),
新生代中的对象大多数生命周期比较短,所以这里的GC发生很频繁。

全收集器

Full GC,指发生在老年代的 GC,出现了 Full GC 一般会伴随着至少一次的 Young GC(老
年代的对象大部分是Young GC 过程中从新生代进入老年代),比如:分配担保失败。Full
GC 的速度一般会比 Young GC 慢 10 倍以上。

什么时候触发GC

  • 当 Eden 空间不足以为对象分配内存时,会触发 Young GC。
  • 当老年代内存不足,或者显式调用 System.gc() 会触发Full GC(也会伴随着执行至少一次的Young GC)。

STW(Stop-the-world)和并发

GC在运行的时候,暂停整个应用就叫STW。
并发这里只的是GC线程和用户线程一起运行,GC可能占用用户的线程。
技术分享图片

串行和并行

串行:垃圾回收的时候只有一个GC线程工作。
并行:垃圾回收的时候有多个GC线程一起工作。
在单核的情况下,并行可能更慢。
技术分享图片

四种主要的垃圾收集器

  • 串行收集器
    适用于单线程系统,适用一个线程进行垃圾回收,会暂停所有的用户线程,不适合服务器环境。
  • 并行收集器
    多个垃圾收集器并行工作,此时用户线程是暂停的,适用于计算/大数据处理,
    适用于弱交互的场景,强调吞吐量。
  • CMS收集器(Concurrent Mark Sweep的简写 并发标记,清除 )
    用户线程和垃圾收集线程同时执行(不一定并行,可能交替执行)不需要暂停用户线程,互联网公司多数使用它,
    适用于强交互,对响应时间有要求的场景。
  • G1收集器
    将堆内存分割成不同的区域,并行的进行垃圾收集。

技术分享图片

后台日志中的部分参数解释

  • DefNew 相当于 Default New Generation的缩写 默认的年轻代使用的垃圾回收器是什么
  • Tenured 相当于 old
  • ParNew 相当于 Parallel New Generation 年轻代使用的是并行回收
  • PSYoungGen 其中ps相当于Parallel Scavenge
  • ParOldGen 相当于Parallel Old Generation 老年底并行垃圾收集器

暂时

技术分享图片
技术分享图片

7种垃圾收集器

垃圾收集的组合

技术分享图片

年轻代收集器(复制算法)

年轻代串行收集器(serial [?s??ri?l] 或serial copying)

特征

单线程收集
收集时必须Stop The Word(停止所有的用户线程)
jvm内存不大时停顿时间短(说明堆内存大小影响GC的效率)

对应JVM参数: -XX:UseSerialGC

配置jvm的时候只需要配置年轻代的收集器即可,jvm会自动选择匹配的老年代收集器。
开启后会使用:年轻代使用Serial +老年代使用的是Serial Old 的收集器组合,说明都是使用的串行。
使用的算法为:年轻代使用复制算法,老年代使用标记-整理算法;

图例:

技术分享图片

年轻代并行收集器(ParNew)

特征

多线程收集(是Serial的多线程版本)
单cpu的效率不及串行收集器Serial,多cpu肯定快于Serial
收集的过程中还是会暂停其他的用户线程。
可以控制ParNew的运行线程数,默认情况下线程数量和CPU核数的数目相同。

常用对应的JVM参数:-XX:UseParNewGC

启用ParNew收集器只会影响年轻代的手机,不影响老年代。
开启后会使用:年轻代使用ParNew收集器, 老年代使用Serial Old 收集器,
注意:jdk8已经不推荐这么组合了!因为Serial Old要被弃用了。
使用的算法为:年轻代使用复制算法,老年代使用标记-整理算法;
-XX:UseParallelGCThreads这个参数可以设置并行收集的线程数。(CPU>8 设置N=5/8 CPU<8 设置Cpu实际个数)

图例

技术分享图片

年轻代并行收集器(Parallel Scavenge)

读音:[?p?r?lel]

和ParNew的区别

  • ParNew在新生代是并行,对应的老年代的却是串行,但是Parallel Scavenge 是并行的。
  • Parallel Scanvenge更强调系统的吞吐

特征

多线程并发收集器,吞吐量优先。
这个收集器通常用于程序运算任务,不需要太多的交互任务。
自适应调节策略也是ParallelScavenge收集器与ParNew收集器的一个重要区别
(虚拟机会根据当前系统的运行情况,动态调整参数设置一个最合适的停顿时间或者最大吞吐量 -XX:MaxGCPauseMillis 这个参数可以设置)
一句话概括:新生代和老年代都使用并行收集。
前面的Serial以及ParNew年轻代的收集器对应的老年代的收集器都是Serial Old都是串行的,这个收集器对应的老年代收集器是并行的(Parallel Old)

  • 什么是系统吞吐量

    系统吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
    系统吞吐量越接近1吞吐量越高。假设运行用户代码的时间为1000ms,垃圾收集时间为100ms,那这个吞吐量结果为:0.90

常用对应的JVM参数:-XX:UseParallelGC 或 -XXUseParallelOldGC 这两个可以相互激活


开启后会使用:年轻代使用Parallel Scavenge收集器, 老年代使用Parallel Old收集器,
使用的算法为:年轻代使用复制算法,老年代使用标记-整理算法;
-XX:UseParallelGCThreads这个参数可以设置并行收集的线程数。

图例

技术分享图片

老年代收集器

老年代串行收集器(Serial Old )

  • 特征

    单线程收集器
    使用的是标记整理算法(可以处理空间碎片问题)
    它和年轻代的Serial以及ParNew配合使用,它被作为老年代收集器CMS的备选收集方案。
    注意:jdk8已经放弃使用了!

技术分享图片

老年代的并行收集器(Parallel Old)

  • Parallel Old 是 Parallel Scavenge 收集器的老年代版本,;
  • 使用多线程和“标记-整理”算法, 注重吞吐量;
    技术分享图片

老年代的并发收集器【CMS 收集器 (Concurrent Mark Sweep 并发标记,清除 )】

特征

CMS是一种以获取最短回收停顿时间为目标的收集器(CMS又称多并发低暂停的收集器)
适用于互联网站或者B/S系统的服务器上,因为GC的停顿时间短,响应速度就快了!
并发收集所以停顿时间短 (注意:这里要区别上面的并行和串行,并发收集指的是GC线程和用户线程是同时运行的。)
采用标记-清除算法(会产生内存碎片问题,执行几次cms会进行一次整理)

基于”标记-清除”算法实现, 整个 GC 过程分为以下 4 个步骤:

技术分享图片

  • 初始标记(CMS initial mark)
    只是标记一下GC Roots能直接关联的对象,并没有把真个引用链标记完整,速度很快,但是需要暂停用户线程。
  • 并发标记(CMS concurrent mark: GC Roots Tracing 过程)
    在这个过程中根据初始标记的对象会把整个对象引用链标记处理,不需要暂停用户线程,和用户线程一起运行
  • 重新标记(CMS remark)
    为了修正在并发标记期间,产生变动对象的那一部分记录,仍然需要暂停用户线程。
  • 并发清除(CMS concurrent sweep: 已死对象将会就地释放, 注意:此处没有压缩)
    清除GC Roots不可达对象,不需要暂停用户线程。
  • 由于耗时最长的并发标记和并发清除过程,都是和用户线程并发执行的,所以总体上来说CMS收集器和用户线程是并发执行的。

缺点:

  • 并发执行对CPU资源压力大
    由于并发进行,CMS在收集与用户线程会同时增加对堆内存的占用,也就是说CMS必须要在老年代对堆内存用尽之前完成一次垃圾回收,否则CMS回收失败时,
    将触发担保机制,串行老年代收集器(Serial Old)将会以STW的方式进行一次GC,从而造成较大停顿。
  • 无法处理浮动垃圾(在并发清除阶段用户线程产生的新的垃圾)
  • CMS是一款“标记--清除”算法实现的收集器,容易出现大量空间碎片,最后不得不通过担保机制对堆内存进行整理压缩。
    我们可以通过参数配置经过多少次CMS才进行一次的整理压缩。
    参数:-XX:CMSFullGCsBeForeCompaction(默认为0,每次都进行内存整理压缩)

JVM对应常用的参数:-XX:UseConcMarkSweepGC

开启该参数会自动将-XX:UseParNewGC打开;
开启后会使用:年轻代使用ParNew 老年代使用CMS+Serial Old(担保)
使用的算法为:年轻代使用复制算法,老年代使用标记-清除,标记-整理

如何查看JVM垃圾收集器?

查看默认的垃圾收集器

使用命令:java -XX:+PrintCommandLineFlags -version
技术分享图片

默认的垃圾收集器有哪些?

我们在配置垃圾收集器的时候只需要指明新生代或者老年代的收集器即可,jvm会自动选择老年代或者新生代的收集器
下面是设置年轻代的GC收集器

  • -XX:+UseSerialGC (自动组合:Serial+Serial Old)
  • -XX:+UseParNewGc (自动组合:ParNew+ Serial Old)
  • -XX:+UseParallelGc (自动组合:Parallel Scavenge +Parallel Old)

下面是设置老年代的GC收集器

  • -XX:+UseConcMarkSweepGC (自动组合:ParNew + CMS+ Serial Old)
  • -XX:+UseParallelOldGc (自动组合:ParallelNew +Parallel Old)
  • -XX:+UseG1GC
  • 从JVM的源代码可以看出:
bool Arguments::check_gc_consistency() {  
  bool status = true;  
  uint i = 0;  
  if (UseSerialGC)                       i++;  
  if (UseConcMarkSweepGC || UseParNewGC) i++;  
  if (UseParallelGC || UseParallelOldGC) i++;  
  if (UseG1GC)                           i++;  
  if (i > 1) {  
    jio_fprintf(defaultStream::error_stream(),  
                "Conflicting collector combinations in option list; "  
                "please refer to the release notes for the combinations "  
                "allowed\n");  
    status = false;  
  }  

  return status;

技术分享图片

查看正在运行的JVM垃圾收集器?

  • 使用jps查出进程,使用jinfo打印运行的jvm参数 jinfo -flags PID

  • 可以使用Jconsole,jvisualvm可视化工具进行查看

  • 在项目启动的时候添加JVM参数:-XX:+PrintCommandLineFlags 也可以获得。

生产上怎么选择收集器?

jvm运行时数据区

技术分享图片
这个图和上面的jvm总体结构图没有冲突,这里只是强调一个线程在运行方法的时候涉及到的内存。

逃逸分析

  • 决定这个变量或者对象实例是在栈中分配还是堆中分配,逃逸指的是这个变量或者对象实例的作用域是否超过当前方法(逃出了方法)。
    如果一个对象实例仅仅在当前方法中使用,并没有通过【返回值返回出去】或者 【通过调用别的方法时作为参数传递过去】
    那么这个对象就是没有发生逃逸,可以将这个对象分配在java栈空间中,栈空间是随着方法的执行结束而清理的,不需要GC,所以可以提高效率。

  • jvm中逃逸分析是可以设置开关的,默认是开启的。

其他概念

对象的创建过程的内存分配

https://blog.csdn.net/qq906627950/article/details/81324825

对象的引用(强,软,弱,虚)

https://www.cnblogs.com/rgever/p/8902210.html

问题

垃圾收集器和垃圾回收算法的关系?分别请你谈谈?

怎么查看服务器的垃圾收集器是哪个?如何配置垃圾收集器?谈谈你对垃圾收集器的理解?

你知道G1垃圾收集器吗?

生产环服务器变慢,诊断思路和性能评估请你谈谈?

对于jdk自带的jvm监控和性能分析工具用过哪些?一般你是怎么用的?

jvm垃圾收集器

原文:https://www.cnblogs.com/wangsen/p/11119777.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!