JVM之GC(二)
昨天总结了GC之前要做的事情,今天介绍一下主流的GC算法。
先介绍一下几个名词:
Stop The World(STW):JVM进行GC的时候总不能一边清理垃圾一边制造垃圾把,那么垃圾鉴定的准确性根本无法得到保证,所以需要将服务全部停掉那么一瞬间;
Yong GC、Minor GC:年轻代区域的GC,所有的年轻代GC都会触发STW;
Old GC、Major GC:老年代区域的GC,只有串行部分会触发STW;
Full GC:主要针对老年代区域而言的串行GC,会触发STW。
首先说一下年龄分代收集算法,根据对象的存活周期,将堆区分为年轻代(新生代)和老年代。顾名思义,刚生成的对象放入年轻代,勤用勤收集,对象成功经历几轮GC后仍存活下来,便将它移入到老年代中去,如果老年代也满了,那么会触发Full GC。如果你是JVM设计者,你会怎么分配年轻代和老年代的比重呢?老年代收集效率差,存活率高,轻易不要移动这里的对象,如果老年代空间不充足,便会频繁触发Full GC,得不偿失;如果老年代分配过多也不好,对象全都跑到老年代了,长时间不触发清理操作会造成过于碎片化,严重导致空有内存却无法分配的现象。因此堆区应该为老年代和年轻代分配合适的比例,一般为4:1(调优参数:-XX:NewRatio=4)
实际上大多数的JVM都是以年龄分代算法为基础,将堆区划分成独立的两个区域,然后再结合其他的GC算法分开进行GC,从而更高效。
最先提出来的是标记清除法:先将堆区的需要回收的对象标记下来,然后统一回收。它会产生两个问题,首先是效率低下,标记和清理过程的效率都是很低的;然后是碎片问题,剩余的存活的对象分散各处,造成堆区碎片化,不方便为大对象分配内存。
针对上面两个问题,提出了复制算法,把堆区分为一个eden区域和两个小的survivor区域,当需要申请内存时,JVM会在较大的eden区域为其分配空间,当eden区域无法为新对象提供内存时,JVM将其中一个survivor空间和eden空间中存活的对象移到另一个survivor中,然后清空eden和之前使用过的survivor,按此循环,也就是说,总有一个survivor区域是留空的,用来存放其余二者存活的对象。
将上面两个方法对比来看,复制算法更适合用来处理存活率低的内存区域,也就意味着复制量小,更高效,显而易见,它是一个年轻代算法;相对而言,如果用标记清除法处理年轻代,使这片空间过于碎片化,当eden为较大对象分配空间时便会很乏力(实际上大对象或大数组是直接在老年代分配的),而且年轻代应该像他的名字一样高效、快速GC,该算法的标记和清除效率并不高,因此标记清除法更应该拿来处理老年代。
针对标记清除法的碎片化问题以及老年代的特点,有人又提出了一个改进措施,标记整理法,它的思想是:让存活的对象向一端移动,然后从边界处将另一侧所有空间直接清理掉。
前面提到了标记,内存中这么多引用变量,JVM如何寻找它是对象引用类型呢?其实,JVM使用了一组OopMap的数据结构来存放引用类型,在JIT编译和类加载的时候记录下来那些位置是引用,这样GC的时候,JVM就可以快速且准确的完成GC Roots的枚举了。
到这里,又引出了另外一个问题,变量、对象间的引用关系是一直在变化的,JVM不可能监听每一条指令,代价太大。所以引出了安全点这个概念,如果在安全点位置上我们对OopMap进行校准的话,那么JVM是可以在这个位置进行GC的,此时STW之后的引用类型是准确的。那么什么位置可以作为安全点呢?1、所有指令的末尾均可添加 2、方法调用、循环回跳之前等可添加; 它的选定是依据“程序在此处是否会长时间执行”为标准的。
对于多线程的程序,STW的时候是需要全部暂停的,但我们并不能保证多个线程正在执行的指令处是否有安全点,上一段已经说明只有安全点处才可以安全准确的GC。这里有两种解决方案:
1、抢先式中断:JVM觉得可以GC了,那就先STW,然后检查所有线程是否在安全点上,不在的话就让它继续执行;很少JVM会采用这种方式
2、主动式中断:在安全点上加一个轮询的标志,在需要GC时,将该标志设为中断值,已经在安全点上的线程便会轮询等待,未在安全点上的线程读取不到这个标志会继续执行
如果一个线程没有分配到时间片,线程出于sleep或blocked状态如何处理呢?JVM不可能等到它分配时间片之后在GC把。因此提出了安全区域这个概念,只有这段指令不会导致引用变化的片段才可以作为安全区域使用,在GC时JVM会忽视掉处于安全区域的线程,在这个区域内的任何地方开始GC都是安全的。当线程执行到安全区域的代码时,首先标识自己进入了安全区域。如果它要走出安全区域,需要先检查JVM是否处于GC状态且是否已经完成了根节点枚举,如果满足了根节点枚举或不在GC状态,它就可以走出来继续执行代码,否则他必须得等待知道收到信号为止。
JVM之GC(二)的更多相关文章
- 深入JVM系列(二)之GC机制、收集器与GC调优
一.回想JVM内存分配 须要了解很多其它内存模式与内存分配的,请看 深入JVM系列(一)之内存模型与内存分配 1.1.内存分配: 1.对象优先在EDEN分配 2.大对象直接进入老年代 3.长期存活的 ...
- 深入JVM系列(二)之GC机制、收集器与GC调优(转)
一.回顾JVM内存分配 需要了解更多内存模式与内存分配的,请看 深入JVM系列(一)之内存模型与内存分配 1.1.内存分配: 1.对象优先在EDEN分配2.大对象直接进入老年代 3.长期存活的对象 ...
- JVM的GC概述
JVM的GC概述 GC即垃圾回收,是指jvm用于释放那些不再使用的对象所占用的内存.在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能. 有些垃圾收集专用于特殊的应用程序.比如,实时应用程序 ...
- JVM 系列(二)内存模型
02 JVM 系列(二)内存模型 一.JVM 内存区域 JVM 会将 Java 进程所管理的内存划分为若干不同的数据区域.这些区域有各自的用途.创建/销毁时间: 一. 线程私有区域 线程私有数据区域生 ...
- JVM之GC算法的实现(垃圾回收器)
上一节:<JVM之GC算法> 知道GC算法的理论基础,我们来看看具体的实现.只有落地的理论,才是真理. 一.JVM垃圾回收器的结构 JVM虚拟机规范对垃圾收集器应该如何实现没有规定,因为没 ...
- 聊一聊 JVM 的 GC
原文链接:https://www.changxuan.top/?p=1457 引言 JVM 中的 GC 在技术博客中应该算是个老生常谈的话题,网络上也存在着许多质量参差不齐的文章,可以看出来大都是&q ...
- Linux使用jstat命令查看jvm的GC情况
Linux使用jstat命令查看jvm的GC情况 http://www.open-open.com/lib/view/open1390916852007.html http://www.aiuxian ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- poptest老李谈jvm的GC
poptest老李谈jvm的GC poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:90882 ...
随机推荐
- 你看Http的 三次握手
你看Http的 三次握手 按层次分,TCP位于传输层,而且TCP协议能够确认数据是否送达到对方,所以在客户端请求资源的时候,你得让俺知道咱俩关系是不是已经确定了啊,对不.这跟谈恋爱一样一样的,得先确定 ...
- 常用的python内建函数
raw_input() 函数说明 函数签名:raw_input([prompt]) 使用形式如下: raw_input([prompt]) -> string 如果提供了参数prompt,就会在 ...
- Mysql5.5升级到5.7的过程已经踩到的坑
https://blog.csdn.net/u014534986/article/details/79699750 故事是这样子的,我们公司有几台老的mysql版本是5.5的,最近项目做了一些升级增加 ...
- [转]在Windows中安装Memcached
Memcached是一个高并发的内存键值对缓存系统,它的主要作用是将数据库查询结果,内容,以及其它一些耗时的计算结果缓存到系统内存中,从而加速Web应用程序的响应速度. Memcached最开始是作为 ...
- linux版本依赖
记住, 你的模块代码一定要为每个它要连接的内核版本重新编译 -- 至少, 在缺乏 modversions 时, 这里不涉及因为它们更多的是给内核发布制作者, 而不是开发者. 模块 是紧密结合到一个特殊 ...
- mysql报错:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
mybatis链接mysql,启动服务报错: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecogni ...
- Linux 内核设备属性
sysfs 中的设备入口可有属性. 相关的结构是: struct device_attribute { struct attribute attr; ssize_t (*show)(struct de ...
- Vscode 开发插件
vs常用公共插件 Auto Close Tag 自动闭合标签 Auto Rename Tag 自动重命名标签 AutoFileName 自动联想文件名 Autoprefixer 自动兼容前缀 Auto ...
- java 环境 笔记
1. 下载idea https://blog.csdn.net/yl1712725180/article/details/80309862 破解方法: 针对20 ...
- P3803 FFT求多项式系数
P3803 FFT求多项式系数 传送门:https://www.luogu.org/problemnew/show/P3803 题意: 这是一道FFT模板题,求多项式系数 题解: 对a和b的系数求一个 ...