一起了解早期使用的各种垃圾网络器

打印 上一主题 下一主题

主题 857|帖子 857|积分 2571


以上是 HotSpot 虚拟机中的 7 个垃圾网络器,连线表示垃圾网络器可以配合使用。
并行网络: 指多条垃圾网络线程并行工作,但此时用户线程仍处于等候状态。
并发网络: 指用户线程与垃圾网络线程同时工作(不一定是并行的可能会交替执行)。用户步调在继承运行,而垃圾网络步调运行在另一个CPU上
吞吐量: 即CPU用于运行用户代码的时间与CPU总斲丧时间的比值(吞吐量 = 运行用户代码时间 / ( 运行用户代码时间 + 垃圾网络时间 )),也就是。例如:虚拟机共运行100分钟,垃圾网络器花掉1分钟,那么吞吐量就是99%
串行Serial / Serial Old 网络器

特点:单线程、简单高效(与其他网络器的单线程相比),采用复制算法。对于限定单个CPU的环境来说,Serial网络器由于没有线程交互的开销,专心做垃圾网络天然可以获得最高的单线程网络效率。网络器举行垃圾回收时,必须暂停其他所有的工作线程,直到它竣事(Stop The World)参数:-XX:+UseSerialGC  -XX:+UseSerialOldGC

安全点: 让其他线程都在这个点停下来,以免垃圾回收时移动对象地址,使得其他线程找不到被移动的对象因为是串行的,所以只有一个垃圾回收线程。且在该线程执行回收工作时,其他线程进入阻塞状态
Serial Old是Serial网络器的老年代版本:采用标志整理算法
特点:

  • 单线程网络器

    • 网络效率高,不会产生对象引用变更
    • STW时间长

  • 使用场景:适合内存小几十兆以内,比较适合简单的服务或者单CPU服务,制止了线程交互的开销。
  • 优点:小堆内存且单核CPU执行效率高。
  • 缺点:堆内存大,多核CPU不适合,回收时长非常长。
ParNew 网络器

年轻代:-XX:+UserParNewGC 老年代搭配 CMS
ParNew网络器其实就是Serial网络器的多线程版本

  • 特点: 多线程、ParNew网络器默认开启的网络线程数与CPU的数量类似,在CPU非常多的环境中,可以使用-XXarallelGCThreads参数来限定垃圾网络的线程数。和Serial网络器一样存在Stop The World问题

CMS 网络器

老年代:-XX:+UserConcMarkSweepGC年轻代搭配ParNew
Concurrent Mark Sweep,一种以获取最短回收停顿时间为目标的老年代网络器

  • 特点: 基于标志扫除算法实现。并发网络、低停顿,但是会产生内存碎片

运行过程分分为下列4步:

  • 初始标志: 标志GCRoots直接关联的对象以及年轻代指向老年代的对象,会发生Stop the word。但是这个阶段的速度很快,因为没有向下追溯,即只标志一层。
例如:Math math = new Math();此时new Math()即为math的直接引用对象,再往下为间接引用不做记录,例如构造方法中引用了其他成员变量

  • 并发标志: 接着从gc roots的直接引用对象开始遍历整条引用链并举行标志,此过程耗时较长,但无需停顿用户线程,可与垃圾网络线程一起并发运行。由于用户线程继承运行,因此可能会导致已经标志过的对象状态发生改变,这个阶段采用三色标志算法, 在对象头(Mark World)标识了一个颜色属性,差别的颜色代表差别阶段,扫描过程中给与对象一个颜色,记录扫描位置,防止cpu时间片切换不必要重新扫描。
  • 重新标志: 为了修正并发标志期间因用户步调继承运行而导致标志产生变动的那一部分对象的标志记录。仍旧存在Stop The World问题,这里会慢一些
  • 并发清算: 标志竣事之后开启用户线程,同时垃圾网络线程也开始对未标志的地区举行扫除,此阶段如有新增对象则会被标志为玄色,不做任那边理
在整个过程中耗时最长的并发标志和并发扫除过程中,网络器线程都可以与用户线程一起工作,不必要举行停顿。

  • 应用场景:适用于注意服务的响应速度,希望系统停顿时间最短,给用户带来更好的体验等场景下。如web步调、b/s服务
  • 优点:

    • 并发网络;
    • STW时间相对短,低停顿;

  • 缺点:

    • 吞吐量低: 低停顿时间是以牺牲吞吐量为代价的,导致 CPU 使用率不够高。
    • 内存碎片问题:CMS本质上是实现了标志扫除算法的网络器,这意味着会产生内存碎片,当碎片化非常严重的时候,这时候有大对象进入无法分配内存时会触发FullGC,特别场景下会使用Serial网络器,导致停顿不可控。
    • 无法处置惩罚浮动垃圾,必要预留空间,可能出现 Concurrent Mode Failure。浮动垃圾是指并发扫除阶段由于用户线程继承运行而产生的垃圾,这部分垃圾只能到下一次 GC 时才能举行回收。由于浮动垃圾的存在,因此必要预留出一部分内存,意味着 CMS 网络不能像别的网络器那样等候老年代快满的时候再回收。如果预留的内存不够存放浮动垃圾,就会出现 Concurrent Mode Failure,这时虚拟机将临时启用 Serial Old 来替换 CMS,会导致停顿时间更长

三色标志算法

三色标志

  • 玄色:代表了自己已经被扫描完毕,并且自己的引用对象也已经确定完毕。
  • 灰色:代表自己已经被扫描完毕了, 但是自己的引用还没标志完。
  • 白色:则代表还没有被扫描过。标志过程竣事后,所有未被标志的对象都是不可达的,可以被回收。
三色标志算法的问题场景:当业务线程做了对象引用变更,会发生B对象不会被扫描,当成垃圾回收。
  1. public class Demo3 {
  2.     public static void main(String[] args) {
  3.         R r = new R();
  4.         r.a = new A();
  5.         B b = new B();
  6.         // GCroot遍历R, R为黑色, R下面的a引用链还未扫完置灰灰色,R.b无引用, 切换时间分片
  7.         r.a.b = b;
  8.         // 业务线程发生了引用改变, 原本r.a.b的引用置为null
  9.         r.a.b = null;
  10.         // GC线程回来继续上次扫描,发现r.a.b无引用,则认为b对象无任何引用清除
  11.         r.b = b;
  12.         // GC 回收了b, 业务线程无法使用b
  13.     }
  14. }
  15. class R {
  16.     A a;
  17.     B b;
  18. }
  19. class A {
  20.     B b;
  21. }
  22. class B {
  23. }
复制代码

当GC线程标志A时,CPU时间片切换,业务线程举行了对象引用改变,这时候时间片回到了GC线程,继承扫描对象A, 发现A没有任何引用,则会将A赋值玄色扫描完毕,如许B则不会被扫描,会标志B是垃圾, 在清算阶段将B回收掉,错误的回收正常的对象,发生业务异常。
CMS基于这种错误标志的解决方案是接纳写屏蔽 + 增量更新Incremental Update , 在业务线程发生对象变化时,重新将R标识为灰色,重新扫描一遍,Incremental Update 在特别场景下还是会产生漏标。即当玄色对象被新增一个白色对象的引用的时候,记录下发生引用变更的玄色对象,并将它重新改变为灰色对象,重新标志。
  1. public class Demo3 {
  2.     public static void main(String[] args) {
  3.         // Incremental Update还会产生的问题
  4.         R r = new R();
  5.         A a = new A();
  6.         A b = new A();
  7.         r.a1 = a;
  8.         // GC线程切换, r扫完a1, 但是没有扫完a2, 还是灰色
  9.         r.a2 = b;
  10.         // 业务线程发生引用切换, r置灰灰色(本身灰色)
  11.         r.a1 = b;
  12.         // GC线程继续扫完a2, R为黑色, b对象又漏了~
  13.     }
  14. }
  15. class R {
  16.     A a1;
  17.     A a2;
  18. }
  19. class A {
  20. }
复制代码
当GC 1线程正在标志O, 已经标志完O的属性 O.1, 准备标志O.2时,业务线程把属性O,1 = B,这时候将O对象再次标志成灰色, GC 1线程切回,将O.2线程标志完成,这时候认为O已经全部标志完成,O标志为玄色, B对象产生了漏标, CMS针对Incremental Update产生的问题,只能在remark阶段,暂停所有线程,将这些发生过引用改变过的,重新扫描一遍。
吞吐量优先Parallel


  • 多线程
  • 堆内存较大,多核CPU
  • 单位时间内,STW(stop the world,停掉其他所有工作线程)时间最短
  • JDK1.8默认使用的垃圾回收器

Parallel Scavenge 网络器

新生代网络器,基于复制算法实现的网络器。特点是吞吐量优先,故也称为吞吐量优先网络器,能够并行网络的多线程网络器,允许多个垃圾回收线程同时运行,降低垃圾网络时间,提高吞吐量。 Parallel Scavenge 网络器关注点是吞吐量,高效率的使用 CPU 资源。 CMS 垃圾网络器关注点更多的是用户线程的停顿时间。
Parallel Scavenge 网络器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾网络停顿时间的
-XX:MaxGCPauseMillis 参数以及直接设置吞吐量巨细的-XX:GCTimeRatio 参数。

  • -XX:MaxGCPauseMillis 参数的值是一个大于0的毫秒数,网络器将尽量保证内存回收花费的时间不凌驾用户设定值。
  • -XX:GCTimeRatio 参数的值大于0小于100,即垃圾网络时间占总时间的比率,相当于吞吐量的倒数。
该网络器的目标是达到一个可控制的吞吐量。还有一个值得关注的点是:GC自顺应调节策略(与ParNew网络器最重要的一个区别)
GC自顺应调节策略: Parallel Scavenge网络器可设置-XX:+UseAdptiveSizePolicy参数。当开关打开时不必要手动指定新生代的巨细(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRation)、晋升老年代的对象年龄(-XXretenureSizeThreshold)等,虚拟时机根据系统的运行状况网络性能监控信息,动态设置这些参数以提供最优的停顿时间和最高的吞吐量,这种调节方式称为GC的自顺应调节策略。


  • 使用场景:适用于内存在几个G之间,适用于配景计算服务或者不必要太多交互的服务,保证吞吐量的服务。
  • 优点:可控吞吐量、保证吞吐量,并行网络。
  • 缺点:回收期间STW,随着堆内存增大,回收暂停时间增大。
Parallel Old 网络器

是Parallel Scavenge网络器的老年代版本
特点:多线程,采用标志整理算法(老年代没有幸存区)

  • 响应时间优先
  • 多线程
  • 堆内存较大,多核CPU
  • 尽可能让单次STW时间变短(尽量不影响其他线程运行)
面试题专栏

Java面试题专栏已上线,欢迎访问。

  • 如果你不知道简历怎么写,简历项目不知道怎么包装;
  • 如果简历中有些内容你不知道该不该写上去;
  • 如果有些综合性问题你不知道怎么答;
那么可以私信我,我会尽我所能资助你。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表