前面介绍了GC和几种主流的GC算法,这节准备说一下垃圾收集器。垃圾收集器可以分为三类,Yong GC, Old GC, Mixed GC

Yong GC

1、Serial

单线程处理,采用复制算法,通常运行在Client模式下,触发STW

2、ParNew

多线程处理,采用多个线程来执行复制算法,通常运行在Server模式下,触发STW,一般与CMS搭配

3、Parallel Scavenge

可以控制STW时间的收集器,时间设置的越短触发GC的频率也就越高,采用的也是复制算法

Old GC

1、Serial Old

单线程,标记整理算法,STW;可以与上3搭配使用,也可以在CMS触发Full GC时使用

2、Parallel Old

多线程,STW,同上3,它俩搭配使用

3、CMS

主流老年代收集器,以最短停顿时间为目标。标记清除法,GC过程为:初始标记(单线程,耗时短,STW)、并发标记(与用户线程一起执行,耗时长)、重新标记(多线程,STW,用来处理前一步用户所产生的新引用)、并发清除(与用户线程一起执行,耗时长)

CMS三大特点:

CMS默认启动回收线程数量为(CPU数量+1)/3,电脑核数越少对程序影响越大(因为并发标记会占用一部分用户资源);

CMS无法处理浮动垃圾,在并发标记期间用户产生的新的垃圾当次是无法处理的,只能放到下次,因此CMS无法做到空间不足时才GC,它在触发GC之前必须为用户预留足够的空间,否则会报错“Concurrent ModeFailure”,JVM会临时启动备用垃圾收集器串行进行清理(如Serial Old),这次停顿时间反而更长

CMS基于标记清除,因此会碎片化堆区,当无法为大对象无法进入老年代时便会触发Full GC,,JVM提供了参数-XX:+UseCMSCompactAtFullCollection  开关FullGC过程中的内存合并整理功能, -XX:CMSFullGCsBeforeCompaction设置执行多少次不压缩的FullGC后跟着来一次压缩的。

Mixed GC

G1收集器

它是目前最前沿的垃圾收集器,它可以单独使用,具有以下特点:并行与并发(充分利用多核多CPU)、分代收集(yong old)、空间整合(标记整理)、可预测的停顿。它是如何做到的呢?

它把整个Java堆区分为多个大小相等的独立区域(Region),仍保留了老年代和年轻代的概念,但以Region分区为主;它会将各个Region里面的垃圾回收的价值(可释放空间与预测的GC时间)进行排序,在后台维护一个优先列表,在可允许的时间内会优先回收价值最大的Region,这样就达到了高效且时间可控的目的。

读到这里不知道大家有没有发现一个问题,虽然将堆区划分为年轻代和老年代,因为老年代和年轻代是可以相互引用的,那么在可达性判定时JVM是不是仍需要扫描整个堆区才足够安全?扫描的话MinorGC效率会大打折扣,那么在GC频繁的年轻代如何避免老年代所引用的对象被错删呢?其实在老年代有一个Write barrier(写屏障)和card table,card table中存放了所有的老年代对年轻代的引用,所以每次MinorGC的时候查询这个table就可以了。

在G1中是如何处理这个问题的呢?答案是Remembered Set,G1的每个Region都有一个与之对应的Remembered Set,在对引用类型的数据进行写操作时,通过写屏障暂时中断写操作,然后检查这个引用类型所引用的对象是否处于不同的Region中,如果是,便通过Card table把相关引用信息记录到被引用对象所属的Region的Remembered Set中,在GC时,把Set中的对象也考虑进根节点便可以了。

G1收集器的操作流程:初始标记(STW,短)、并发标记(与用户线程并发,长)、最终标记(类似于CMS的重新标记,将浮动垃圾写入Rem Set log然后合并到Rem Set)、筛选回收(按价值排序然后回收)

在这里引用书中的一句话:从JDK1.3到现在,从Serial收集器-》Parallel收集器-》CMS-》G1,用户线程停顿时间不断缩短,但仍然无法完全消除;

JVM之GC(三)的更多相关文章

  1. JVM系列(三)之GC

    什么是GC Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄 ...

  2. 学习笔记:Java的一些基础小知识之JVM与GC

      一.JVM是什么 Java虚拟机(英语:Java Virtual Machine,缩写为JVM),又名爪哇虚拟器,一种能够运行Java bytecode的虚拟机,以堆栈结构机器来进行实做.最早由太 ...

  3. jvm内存GC详解

    一.相关概念  a. 基本回收算法 1. 引用计数(Reference Counting)  比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收 ...

  4. Java的一些基础小知识之JVM与GC (转)

    一.JVM是什么 Java虚拟机(英语:Java Virtual Machine,缩写为JVM),又名爪哇虚拟器,一种能够运行Java bytecode的虚拟机,以堆栈结构机器来进行实做.最早由太阳微 ...

  5. poptest老李谈jvm的GC

    poptest老李谈jvm的GC   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:90882 ...

  6. Linux使用jstat命令查看jvm的GC情况(转)

    B. jstack jstack主要用来查看某个Java进程内的线程堆栈信息.语法格式如下: 1 jstack [option] pid 2 jstack [option] executable co ...

  7. jvm的GC日志分析 [转]

      jvm的GC日志分析 标签: jvm内存javagc 2015-06-22 16:37 1566人阅读 评论(1) 收藏 举报  分类: Java(4)  JVM的GC日志的主要参数包括如下几个: ...

  8. JVM内存模型 三

    本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏   1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉 ...

  9. JVM之GC(一)

    Java较C而言,最大的区别在于内存管理.JVM设有无用内存空间自动回收复用机制,也就是我们所说的GC. 之前说过,栈是为线程.为函数的执行分配内存的地方,用完即“销毁”,这里留待以后做深入探讨:堆是 ...

  10. 叫练手把手教你读JVM之GC信息

    案例 众所周知,GC主要回收的是堆内存,堆内存中包含年轻代和老年代,年轻代分为Eden和Surivor,如下图所示.我们用案例分析下堆的GC信息[版本:HotSpot JDK1.8]. /** * @ ...

随机推荐

  1. windows 关闭端口被占用脚本

    cmd 关闭进程java taskkill /F /IM java.exe taskkill /f /im java.exe 如何用dat批处理文件关闭某端口对应程序-Windows自动化命令 如何用 ...

  2. codedecision P1113 同颜色询问 题解 线段树动态开点

    题目描述:https://www.cnblogs.com/problems/p/11789930.html 题目链接:http://codedecision.com/problem/1113 这道题目 ...

  3. NIO 中文乱码问题的解决代码实现

    之前在网上查询了很多关于解决NIO中文乱码的问题,仁者见仁智者见智,不过就找到的几种方法实现都太繁琐了,稍微研究了下NIO源码,以下是我自己的一种实现,偷懒用最简单的代码去实现是我的习惯! Demo: ...

  4. Python--day63--添加书籍

    添加书籍的代码:

  5. Python--day47--mysql索引注意事项

  6. dotnet 设计规范 · 抽象定义

    严格来说,只有一个类被其他的类继承,那么这个类就是基类.在很多时候,基类的定义是提供足够的抽象和通用方法和属性.默认实现.在继承关系中,基类定义在上层抽象和底层自定义之间. 他们充当抽象实现的实现帮助 ...

  7. 模版——KMP

    #include <iostream> #include <cstdio> #include <cstring> ; int f[maxn]; char P[max ...

  8. H3C 被动方式建立连接过程

  9. Vue2.0 Vue.set的使用

    原文链接: https://blog.csdn.net/qq_30455841/article/details/78666571

  10. Linux 内核驱动结构嵌入

    如同大部分驱动核心结构的情形, device_driver 结构常常被发现嵌到一个更高级的, 总 线特定的结构. lddbus 子系统不会和这样的趋势相反, 因此它已定义了它自己的 ldd_drive ...