接上次JVM虚拟机堆内存模型来继续说,上次我们主要说了什么时候可能把对象直接放在老年代,还有我们的可能性分析,提出GCroot根的概念。这次我们主要来说说垃圾回收所使用的的算法和我们的垃圾回收器,需要了解我们的可达性分析GCroot根是什么,还有我们的动态年龄判断和老年代分配担保机制,还不清楚咋回事的小伙伴可以去我上几篇JVM的博客去看一下,JVM内存模型的几篇博客 https://www.cnblogs.com/cxiaocai/p/11520731.html

  垃圾回收算法,主要就三种,标记清除,复制,标记整理。

标记清除:

  上图说话。

解释一下,标记清理算法,我们可以视为每一个位置去观察,可以清理就标记,不能清理就放那不动。也可以想象为我们打扫屋子,我们只扔掉我们不想要的物品,其余想留下的东西还是放在原处不动。

这种算法清理缺点是效率并不高,而且会带来大量的空间碎片,我们可以由下面的小方格看到,红色的格子不是连续的,而是分布在不同位置的。这时进来一个大对象,需要多个连续的格子,就可能放不下了。

复制:

  不多了直接上图。

和上面相比,我们至少可以看到连续的红格子了,复制算法就是查看每一个小格子,可以回收就回收掉,不行就挪到保留的另一半内存中去,每次只标记整体区域的一半,我们还是拿收拾屋子举例,复制算法就像是,我们把卧室收拾一遍,不要的扔掉,想留下的整齐的放在客厅,下次我们收拾客厅也是如此,每次收拾一半。缺点就是内存利用率低,只能使用一半,还需要保留一半的区域为了来回挪动存活对象。

标记整理:

  

标记整理是是标记清除的升级版,优点:解决内存碎片问题。缺点:整理阶段,由于移动了可用对象,需要去更新引用。还是收拾屋子的那个例子,我们把没用的物品扔掉,其余物品整齐的摆放起来。

接下来就是和我们回收算法对应的回收器了。

Serial收集器(-XX:+UseSerialGC -XX:+UseSerialOldGC)

Serial(串行)垃圾收集器是最基本、发展历史最悠久的收集器;作用于新生代时采用采用复制算法;Serial Old收集器也就是Serial作用于老年代时采用标记整理算法。

采用单线程手机模式来收集。

ParNew收集器(-XX:+UseParNewGC) 

ParNew收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为 (控制参数、收集算法、回收策略等等)和Serial收集器完全一样。默认的收集线程数跟cpu核数相同,当然也可以用参数(-XX:ParallelGCThreads)指定收集线程数,但是一般不推荐修改。 并且单核CPU的服务器,优先考虑Serial收集器,甚至由于存在线程交互的开销,效果不一定强于Serial收集器,可能Serial收集器效果更好,parNew新生代采用复制算法,老年代采用标记-整理算法。 建议使用在新生代,后面会说为什么。

Parallel Scavenge收集器(-XX:+UseParallelGC,- XX:+UseParallelOldGC)

Parallel Scavenge 收集器类似于ParNew 收集器,是Server 模式(内存大于2G,2个cpu)下的默认收集器, Parallel Scavenge更加关注于CPU的使用率,可能在回收的过程瞬间CPU使用率提高进行垃圾回收。Parallel Old收集器是Parallel Scavenge收集器的老年代版本。和上面的图一样 ,我就不再贴图了。新生代采用复制算法,老年代采用标记-整理算法。

CMS收集器(-XX:+UseConcMarkSweepGC(old)) 

  相对上面几个收集器来说稍微复杂一些,先看图。

由图来看确实复杂了不少,但是并不是一直处于STW阶段,中间还有并行的时候。我们来看一下每一个阶段都是做什么的。

初始化标记阶段:

  这里STW时间非常短,微乎其微的,这里只标记GCRoot根直接引用的对象,不往下层去搜索更多的对象进行标记,效率很高,STW时间很短。

并发标记阶段:

  并发标记阶段是最消耗时间的,在上一个阶段只标记GCRoot根的直接引用对象,这个阶段是把所有需要回收的对象都需要标记出来。可能引用很多,所以耗时较大。但是还好,他不会出现STW,不会停掉所有线程为其单一服务。

重新标记阶段:

  在上一个相对比庞大的并发标记阶段,并没有STW,可能会产生新的GCRoot根,或者说原有不需要回收的对象现在已经变为垃圾对象了,我们在重新标记阶段再一次来做一下处理,这里又会出现STW现象,相比并发标记阶段时间也是很短的。

并发清理阶段:

  恢复我们的正常的线程,开始清理没有标记的对象,这里不会产生STW,在这个阶段再进来的新对象,或者产生对象的变更,CMS是不会继续处理的,会在下一次垃圾回收再来处理这些对象。

并发重置阶段:

  清楚所有标记,为下一次垃圾回收做准备。

CMS垃圾收集器步骤比较多,但是我们可以看出明显提高了效率,中间至少不是持续的STW的。但是也有CMS的弊端的,并发标记阶段和并发清理阶段很容易和我们正常的线程抢占CPU的。再就是他的算法只是标记清理,并没有整理内存碎片,但可以调配参数做到整理碎片的目的。最坑的问题来了,就是我们在并发标记阶段,可能进来新的对象,本来我们老年代就快满了,才进行的垃圾收回,这时这些对象过大过多,会再次执行CMS的垃圾回收,造成concurrent mode failure,这时会变更为Serial收集器,产生较长的STW时间。

CMS相关参数:

1. -XX:+UseConcMarkSweepGC:启用cms垃圾回收器
2. -XX:ConcGCThreads:并发的GC线程数目
3. -XX:+UseCMSCompactAtFullCollection:FullGC之后做压缩整理(减少碎片)
4. -XX:CMSFullGCsBeforeCompaction:多少次FullGC之后压缩一次,默认是0,代表每次
FullGC后都会压缩一次,依赖上面的参数,必须配置-XX:+UseCMSCompactAtFullCollection才生效
5. -XX:CMSInitiatingOccupancyFraction: 当老年代使用达到该比例时会触发FullGC(默认
是92,这是百分比),可能出现JVM自我优化变更的现象,不是很稳定
6. -XX:+UseCMSInitiatingOccupancyOnly:只使用设定的回收阈值(-XX:CMSInitiatingOccupancyFraction设定的值),如果不指定,JVM仅在第一次使用设定值,后续则会自动调整,比上面的-XX:CMSInitiatingOccupancyFraction稳定很多
7. -XX:+CMSScavengeBeforeRemark:在CMS GC前启动一次minor gc,目的在于减少
老年代对年轻代的引用,降低CMS GC的标记阶段时的开销,一般CMS的GC耗时 80%都在重新标记阶段

今天先说这么多 ,还有一个G1收集器没有说,下次博客会说G1收集器,和常见的调优方式,有时间我再整理一份常用的命令。

看起来真的吃力的话,建议先看一下我前几篇JVM相关的博客,JVM内存模型的几篇博客 https://www.cnblogs.com/cxiaocai/p/11520731.html

java架构之路-(12)JVM垃圾回收算法和垃圾回收器的更多相关文章

  1. java架构之路-(JVM优化与原理)JVM之G1回收器和常见参数配置

    过去的几天里,我把JVM内部的垃圾回收算法和垃圾回收器.还剩下最后一个G1回收器没有说,我们今天数一下G1回收器和常见的参数配置. G1回收器 G1 (Garbage-First)是一款面向服务器的垃 ...

  2. JVM 垃圾回收算法和垃圾回收器

    JVM 垃圾回收算法和垃圾回收器. 一.垃圾回收的区域 栈:栈中的生命周期是跟随线程,所以一般不需要关注. 堆:堆中的对象是垃圾回收的重点. 方法区:这一块也会发生垃圾回收,不过这块的效率比较低,一般 ...

  3. 直通BAT必考题系列:JVM的4种垃圾回收算法、垃圾回收机制与总结

    垃圾回收算法 1.标记清除 标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段. 在标记阶段首先通过根节点(GC Roots),标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象. ...

  4. java中的垃圾回收算法与垃圾回收器

    常用的垃圾回收算法 标记-清除 标记清除算法是一种非移动式的回收算法,分为标记 清除 2个阶段,简而言之就是先标记出需要回收的对象,标记完成后再回收掉所有标记的内存对象,如下图 可见回收后图中被标记的 ...

  5. Java垃圾回收算法和垃圾回收器

    基本上 jvm内存回收有三种 基本算法 标记-清除 标记清除的算法最简单,主要是标记出来需要回收的对象,然后然后把这些对象在内存的信息清除.如何标记需要回收的对象,在上一篇文章里面已经有说明. 标记- ...

  6. java架构之路-(JVM优化与原理)JVM类的加载机制

    话不多说,先上图. ***.class文件执行大概就是这样来走的.我们都知道我们的java文件经过编译以后会生成对应的class文件.先经过类装载子系统,然后塞进运行时内存模型的元空间,开始执行方法, ...

  7. java架构之路-(JVM优化与原理)JVM的运行时内存模型

    还是我们上次的图,我们上次大概讲解了类加载子系统的执行过程,验证,准备,解析,初始化四个过程.还有我们的双亲委派机制. 我们这次来说一下运行时内存模型.上一段小代码. public class Mai ...

  8. Java垃圾回收算法和内存分配策略

    垃圾回收算法和内存分配策略 Java垃圾回收 垃圾收集,也就是GC并不是Java的伴生物,而对于GC的所需要完成任务主要就是: 1.哪些内存是需要回收的? 2.何时去回收这些内存? 3.以何种方式去回 ...

  9. JVM学习总结二——垃圾回收算法

    昨天总结了JVM内存分区相关的知识,这次我们将来了解下JVM的另一个核心知识点——垃圾回收算法.这一部分其实并不太难,如果对操作系统的内存处理算法有所了解,那么这部分算法其实只看名字就能明白,两者在原 ...

随机推荐

  1. CodeForces 526D Om Nom and Necklace

    洛谷题目页面传送门 & CodeForces题目页面传送门 给定字符串\(a\),求它的每一个前缀,是否能被表示成\(m+1\)个字符串\(A\)和\(m\)个字符串\(B\)交错相连的形式, ...

  2. 洛谷 P3648 [APIO2014]序列分割

    题意简述 有一个长度为n的序列,分成k + 1非空的块, 选择两个相邻元素把这个块从中间分开,得到两个非空的块. 每次操作后你将获得那两个新产生的块的元素和的乘积的分数.求总得分最大值. 题解思路 f ...

  3. AUTOCAD二次开发-----删除一个图层里面的所有对象

    https://blog.csdn.net/aasswwe/article/details/40899759 private void Test() { // 获取当前文档和数据库 Document ...

  4. 【C语言基础】unsigned short类型用于循环的一个难点

    我在我的知识星球:“C语言解惑课堂”里的第一篇提出一个问题:[第1篇][C语言基础][unsigned short类型用于循环的一个难点]要查看更多的C语言难点解析或者需要提问的同学,微信扫扫文末我的 ...

  5. 【win10主机】访问virtualbox上【32位winXP系统虚拟机】上启动的项目

    win10上创建虚拟网卡: 1,右键此电脑点击管理——设备管理器——网络适配器: 2,点左上角菜单栏的 操作——添加过时硬件: 3,点下一步 4,点安装我手动从列表选择的硬件(高级)M 5,点网络适配 ...

  6. Python模块之ncclient

    一.简介 此模块是是netconf协议的客户端,可与netconf服务端进行交互 二.实验环境 1.操作系统:win10 2.python版本:python3.6.6 3.ncclient模块版本:0 ...

  7. python + selenium webdriver 复合型css样式的元素定位方法

    <div class="header layout clearfix"></div> 当元素没有id,没有name,没有任何,只有一个class的时候,应该 ...

  8. 利用QGIS下载地图数据

    这段时间做了一些利用地理信息进行定位导航的系列工作,其中很重要的一部分是如何获取到地图数据,比如道路的矢量图.某一区域的栅格图,我用到的主要工具是QGIS.QGIS是一个跨平台的免费应用,其中集成了对 ...

  9. 持续集成高级篇之Jenkins Pipeline git拉取

    系列目录 PipeLine中拉取远程git仓库 前面讲自由式任务的时候,我们可以看到通过自由式job里提供的图形界面配置git拉取非常方便的,实际上使用PipeLine也并不复杂.这一节我们展示一下如 ...

  10. Web前端安全分析

    随着互联网高速的发展,信息安全已经成为企业重点关注焦点之一,而前端又是引发安全问题的高危据点,所以,作为一个前端开发人员,需要了解前端的安全问题,以及如何去预防.修复安全漏洞. 一.XSSS攻击 1. ...