你必须了解的java内存管理机制(四)

  • 时间:
  • 浏览:4
  • 来源:松果娱乐网 - 专注共享吾爱分享资讯

  前面介绍的几种收集器都相对比较简单,也很好理解,如可让 如可让 也没做太多的介绍。接下来介绍的收集器相对前面几种收集器就要复杂化如可让 ,如可让使用较广,如可让 如可让 介绍会较详细!并发标记清理(Concurrent Mark Sweep)收集器也称为并发低停顿收集器或低延迟收集器。CMS收集器采用的是“标记-清理”算法,如可让 如可让 我太多 进行压缩操作。亲戚亲戚朋友先来了解一下CMS收集器的运作过程:

  “标记-收集”算法的标记过程与“标记-清除”算法是一样一样的,但后续步骤都不 直接对可回收对象进行清理,却说让所有的对象都向一端移动,如可让直接清理掉端边界以外的内存。执行过程如下图:

  在Hotspot虚拟机中,新生代的收集器都不 采用的改良版的好友克隆算法进行垃圾回收。将新生代一分为三,一块Eden区和两块Survivor区。Eden区与两块Survivor区的比例为8:1:1。一个多多 划分的土方式是哪几种呢?基于弱代理论,IBM研究表明新生代中98%的对象都不 "朝生夕死",大多数分配了内存的对象从我太多 存活太长时间,在所处年轻代时就会死掉。

  优点:

    1、改善了“标记-清除”算法会产生内存碎片的缺点。

    2、我太多 像“好友克隆”算法那样速率随对象存活率升高而变低。

  缺点:

    1、 依然没有出理 “标记-清除”算法所处的缺点,那却说回收速率间题。还多了才能 收集的过程,速率更低。

  并行收集器是串行收集器的多程序运行版本,除了多程序运行外,其余的行为、特点和串行收集器一样。主要中含ParNew收集器、Parallel Scavenge收集器、Parallel Old收集器。运行示意图如下:

  2、并发标记(CMS Concurrent mark)

  进行GC Roots Tracing的过程,也却说查找GC Roots能直接关联的对象所引用的内存。在这些阶段,GC程序运行与用户程序运行是一块儿运行的,如可让 如可让 从必须保证能标记出所有存活的对象。

  

  上一篇文章中,亲戚亲戚朋友详细介绍了三种生活标记算法,如可让对可达性分析算法做了较多的介绍。亲戚亲戚朋友也知道了HotSpot在具体实现中为什利用OopMap+RememberedSet的技术做到“准确式GC”。不管使用哪几种优化的技术,目标都不 准确高效的标记回收对象!没有,为了高效的回收垃圾,虚拟机又经历了哪几种技术及算法的演变和优化呢?(注:G1收集器及回收算法本文不涉及,完后 虽然里面还才能 单独写一篇文章来谈!)

  串行垃圾收集器是最基本、发展历史最悠久的收集器。主要中含Serial和Serrial Old三种生活收集器,分别用来收集新生代和老年代。串行收集器完后 是单程序运行收集,在进行垃圾收集时,才能 暂停(Stop The World)所有的工作程序运行,直到GC程序运行工作完成。运行示意图如下:

  在前面三篇文章中,对JVM的内存布局、内存分配、垃圾标记做了较多的介绍,垃圾都完后 标记出来了,那剩下的却说如可高效的去回收啦!这篇文章将重点介绍如可回收旧手机、电脑、彩电、冰箱~啊呸(⊙o⊙)…将重点介绍几种垃圾回收算法、HotSpot中常用的垃圾收集器的主要特点和应用场景。一块儿,这篇文章也是这些系列中的最后一篇文章啦!

  优点:

    1、每次针对半个区域进行回收,实现简单,运行高效。

    2、我太多 产生内存碎片间题。

  缺点:

    1、 内存会缩小为一个多多 的一般,代价高。

    2、 当对象存活率较高时,才能 进行较多好友克隆操作,速率完后 变低。

  4、 “Concurrent Mode Failure”失败

  我想知道亲戚亲戚朋友在开发过程中含没有遇到过“Concurrent Mode Failure”失败的信息,不管你有没有遇到过,反正我是遇到过!这些异常是哪几种愿因愿因的呢。在并发标记和并发清除阶段,用户程序运行与GC程序运行并发工作,这会愿因在清理的完后 又会有用户的程序运行在拼命的创建对象,三种生活垃圾回收完后 肯定是可用内存缺陷了,可万一这完后 用户程序运行创建了多量的对象为什办呢?如可让 如可让 一般CMS收集器的垃圾回收的动作我太多 在详细无法分配内存的完后 进行,还才能 通过“-XX:CMSInitiatingOccupancyFraction”参数来设置CMS预留的内存空间!完后 预留的空间无法满足程序运行的才能 ,就会出现 “Concurrent Mode Failure”失败。这完后 JVM会启用后备方案,也却说前面介绍过的Serial Old收集器,一个多多 会愿因另一次的Full GC的产生,一个多多 的代价是很大的,如可让 如可让 CMSInitiatingOccupancyFraction这些参数设置才能 根据程序运行合理设置

本文在如可让 人技术博客不同步发布,详情可用力戳

亦可扫描屏幕右侧二维码关注如可让 人公众号,公众号内有如可让 人联系土方式,等你来撩...

  完后 老年代的对象存活周期一般相对较长,我太多 像新生代对象那样“朝生夕死”,如可让 如可让 对象存活率高是老年代的特点,如可让老年代也没有额外的空间还才能 分配担保,如可让 如可让 不适合采用好友克隆算法进行回收。根据老年代的特点,一般会使用"标记-清理"或"标记-收集"算法来进行垃圾回收。

  里面亲戚亲戚朋友介绍了在JVM中常用的垃圾回收算法及每三种生活算法的优缺点。接下里会介绍在HotSpot虚拟机中常用的几种垃圾收集器,垃圾收集器是垃圾回收算法的具体实现,不同的商家、不同版本的JVM所提供的垃圾收集器完后 会所处差异。这几种收集器分别是Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1。在了解垃圾收集器完后 ,亲戚亲戚朋友先来区分十几个 概念:

  3、重新标记(CMS remark)

  完后 并发标记阶段,用户程序运行在并发运行,如可让 如可让 完后 在并发标记阶段产生新的对象,如可让 如可让 在重新标记阶段也会才能 “Stop The World”来标记新产生的对象,且停顿时间比初始标记时间稍长,但远比并发标记短。

  

  在原始的好友克隆算法中,空间一分为二,空间利用率为1000%,也却说说有新生代中1000%的空间会被浪费,无法分配内存。Hotspot虚拟机使用改良的好友克隆算法,如可让设置合理的空间比例,新生代中可用的内存空间为整个新生代容量的90%,必须10%的空间会被浪费,大大的提高的新生代的空间利用率。完后 存活对象占用的内存大于新生代容量的10%为什办?这就才能 依赖如可让 内存(老年代)进行分配担保了。新生代回收动图如下:

  YoungGC VS OldGC VS MinorGC VS MajorGC VS FullGC

  Minor GC、YoungGC:Minor GC又称为新生代GC,如可让 如可让 等价于Young GC,在新生代的Eden区分配满的完后 触发。在Young GC后新生代中含累积存活对象会晋升到老年代,有完后 是年龄达到阈值(默认为15岁,在JVM里面15岁就步入老年生活了,O(∩_∩)O哈哈~)了,也完后 是Survivor区域满了,完后 是Survivor区域被填满,会将所有新生代中存活的对象移动到老年代中!

  

  2、 产生多量内存碎片

  CMS收集器采用“标记-清除”算法,在清除后我太多 进行压缩操作,一个多多 会愿因产生多量不连续的内存碎片,在分配大对象时,无法找到足够的连续内存,从而才能 提前触发一次FullGC的动作。针对该间题,提供了一个多 参数来设置否是是开启碎片收集。

  1)、“-XX:+UseCMSCompactAtFullCollection”参数

  从名字能看出来,在收集的完后 否是是开启压缩。这些参数默认是开启的,如可让否是是开启压缩还才能 结合下面的参数!

  2)、“-XX:+CMSFullGCsBeforeCompaction”参数

  该参数设置执行十几个 次不压缩的Full GC后,来一次压缩收集。这些参数默认为0,也却说说每次都执行Full GC,我太多 进行压缩收集。

  完后 开启了压缩,则在清理阶段才能 “Stop the world”,必须进行并发!

  Major GC、Old GC、Full GC:Old GC从字面能理解是老年代的GC,如可让对Major GC和Full GC所处多种说法,有的认为Major GC等价于Old GC却说针对老年代的GC,有的认为Major GC和Full GC是等价的。如可让我如可让 人认为Major是指老年代GC,而Full GC针对新生代、老年代、永久代整个的回收。完后 老年代的GC都不 伴随一次新生代的GC,如可让 如可让 习惯性的把Major GC和Full GC划上了等号。前面Young GC完后 说到“在Young GC后新生代中含累积存活对象会晋升到老年代”,万一老年代的空间缺陷存放新生代晋升的对象为什办呢?如可让 如可让 当准备要触发一次Young GC时,完后 发现统计数据完后 Young GC的平均晋升大小比目前老年代剩余的空间大,则我太多 单独触发Young GC,却说转为触发Full GC,也却说整堆的收集!

  

  串行收集器在单CPU的环境下,没有程序运行切换的开销,还才能 获得最高的单程序运行收集速率,如可让完后 现在普遍都不 多CPU(完后 多核)环境,如可让 如可让 除了在桌面应用中仍然将串行收集器作为默认的收集器,如可让 场景完后 很少(很少不代表没有,里面CMS会讲到)使用。

  1、初始标记(CMS initial mark)

  仅标记GC Roots能直接关联的对象,这些阶段为速率较快,如可让仍然才能 “Stop The World”,如可让停顿时间较短!

  亲戚亲戚朋友都知道,在主流的虚拟机中都不 采用分代收集算法来进行堆内存的回收,在第一篇文章中亲戚亲戚朋友也用了一张图展示了JVM堆内存的划分。如下:

  ParNew收集器:主要针对新生代回收,采用好友克隆算法,多程序运行收集。一般老年代完后 使用CMS收集器,则默认会使用ParNew作为新生代收集器

  Parallel Scavenge收集器:该收集器与ParNew收集器之类,也是新生代收集器,采用好友克隆算法,多程序运行收集。如可让 收集器关注点是尽完后 地缩短垃圾收集时用户程序运行停顿的时间,如可让Parallel Scavenge收集器的目标则是达到一个多 可控的吞吐量(吞吐量=CPU运行用户代码时间/(CPU运行用户代码时间+CPU垃圾收集时间)),如可让 如可让 该收集器也成为吞吐量收集器。完后 该收集器没有使用传统的GC收集器代码框架,是另外独立实现的,如可让 如可让 无法和CMS收集器配合工作。

  Parallel Old收集器:主要针对老年代回收,采用“标记-收集”算法,多程序运行收集。该收集器是Parallel Scavenge收集器的老年代版本。在JDK1.6完后 用来替代老年的Serial Old收集器。在注重吞吐量以及CPU资源敏感的场景,一般会选折 Parallel Scavenge+Parallel Old的组合进行垃圾收集。

  

相关链接(注:文章讲解JVM以Hotspot虚拟机为例,jdk版本为1.8)

1、 你才能 了解的java内存管理机制-运行时数据区

2、 你才能 了解的java内存管理机制-内存分配

3、 你才能 了解的java内存管理机制-垃圾标记

4、 你才能 了解的java内存管理机制-垃圾回收

  在里面亲戚亲戚朋友谈到一个多 词,才能 暂停(Stop The World)所有的工作程序运行,这些概念在里面也会多次提到,为哪几种才能 暂停呢?一是为了方便GC动作,不然在GC过程中又会额外产生新的垃圾,完后 分配新的对象。二是完后 GC过程中对象的地址会所处变化,完后 不暂停程序运行,完后 会愿因引用出现间题。

  “好友克隆算法改良版”替代一个多多 将内存一分为二的方案,将内存分为一块较大的内存(称为Eden空间)和两块较小的内存(称为Survivor空间),每次使用Eden空间和其中一块Survivor空间。当回收时,将Eden和其中一块Survivor中还存活的对象一次性好友克隆到另外一块Survivor空间上,最后清理掉Eden和刚才使用过的Survivor空间。执行过程如下图:

  优点:

    1、改善了普通好友克隆算法的缺点,提高了空间利用率

  

  优点:

    1、基于最基础的可达性分析算法,它是最基础的收集算法。

    2、后续的收集算法都不 基于这些思路并对其缺陷进行改进而得到的。

  缺点:

    1、 执行速率不高。

    2、 由上图能看后这些回收算法会产生多量不连续内存碎片,完后 这完后 才能 创建一个多 大对象,则无法进行分配。

  里面介绍了CMS收集器的缺点,那它当然都不 它的优点啦,比如并发收集、低停顿等等……如可让 如可让 CMS收集器适合与用户交互较多的场景,注重服务的响应速率,能给用户带来较好的体验!如可让 如可让 亲戚亲戚朋友在做WEB开发的完后 ,时不可以 使用CMS收集器作为老年代的收集器!

  “好友克隆”算法将内存按容量划分为大小相等的两块,每次使用其中的一块。当一块的内存用完了,就将还存活的对象好友克隆到另一块里面,如可让将完后 使用过的存储空间一次性清理掉,一个多多 每次都不 针对整个半区的内存进行回收,我太多 考虑碎片间题。执行过程如下图:

  

  在这里,亲戚亲戚朋友会先介绍几种常用的回收算法,如可让了解在JVM中式如可对这几种算法进行选折 和优化的。

  分代回收根据对象存活周期的不同将内存划分为十几个 ,一个多多 就还才能 根据各个年代的特点采用最适当的收集算法。一般把Java堆分为新生代老年代

  1、 对CPU资源非常敏感

  并发收集虽然我太多 暂停用户程序运行,如可让完后 会占用一累积CPU资源,还是会愿因程序运行运行更慢,总吞吐量下降。CMS的默认收集程序运行的数量=(CPU数量+3)/4。如可让 如可让 ,当CPU数量大于一个多 时,会有超过25%的资源用于垃圾收集。当CPU数量小于或等于一个多 时,默认一个多 收集程序运行。

  

  4、并发清除(CMS Concurrent sweep)

  在并发清除阶段用户程序运行与清理程序运行也是一块儿工作,清理程序运行回收所有的垃圾对象!

  3、 产生浮动垃圾

  里面说到过在并发清理阶段,用户程序运行还在运行,这完后 完后 就会又有新的垃圾产生,而无法在此次GC过程中被回收,这成为浮动垃圾。

  Serial 收集器:主要针对新生代回收,采用好友克隆算法,单程序运行收集。

  Serial Old收集器:主要针对老年代回收,采用“标记-收集”算法,单程序运行收集。

  "标记-清除"算法分为一个多 阶段,“标记”和“清除”。标记还是那个标记,在上一篇文章中完后 做了较多的介绍了,JVM在执行完标记动作后,还在"即将回收"集合的对象将被统一回收。执行过程如下图:

  并发收集器VS并行收集器

  并行:指多条收集程序运行一块儿进行收集工作,但此时用户程序运行所所处等待情況。如ParNew、Parallel Scavenge、Parallel Old。

  并发:指用户程序运行与垃圾收集程序运行一块儿执行(从不一定是并行,完后 会交替执行)。如CMS、G1。

  里面了解了CMS收集器的运作过程,我想知道在了解过程中你有没有发现如可让 间题,比如CMS收集器采用的是“标记-清除”算法,那会我太多 产生如可让 如可让 的内存碎片?比如在并发清理阶段,用户程序运行还在运行,会我太多 在清理的过程中又产生了垃圾?总结CMS收集器的十几个 明显的缺点如下: