Java成神之路——JVM垃圾回收概览
如何确认对象可以被回收
枚举根节点,来确认, 搜索对象的引用链. 当一个对象的引用不能到达根节点,那么就认为这个对象是垃圾.
根节点可以为: 虚拟机栈中引用的对象,方法区中类静态属性引用的遍历,方法区中常量引用的对象,本地方法栈中JNI 也就是native方法 引用的对象
常见的垃圾回收算法
标记清除:
首先标记出需要回收的对象,然后进行清除,效率不高,会产生大量的内存碎片,内存碎片太多可能在分配大对象时找不到连续的内存空间从而提前导致提前gc。
清理前:
标记清除后:
标记整理:
标记出需要回收的对象,所有存活的对象向一端移动,然后清理掉端边界外的内存,避免内存碎片的产生。
清理前:
标记整理后:
复制算法:
将内存分为两块,每次只使用其中的一块,当其中的一块用完了,把存活的对象复制到另一块,然后清除此块内存。复制算法在对象存活率较高的情况下回进行较多的复制,效率变低。
清理前:
复制算法清理后:
分代收集:
一种综合的方式, 根据生命周期的不同,将堆分为新生代和老年代,新生代中容易产生垃圾,采用复制算法,每次只需要少量复制即可,老年代对象存过概率高,采用标记清除或标记整理
回收算法优缺点
标记清除缺点: 标记和清除两个过程的效率都不高,另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致之后再程序运行过程中需要分配大对象的时候,无法找到足够的连续内存而不可不提前触发一次垃圾收集动作.
标记整理优缺点: 不会产生内存碎片,但是整理需要花费额外的时间
复制算法优缺点: 没有内存碎片,但原有的内存缩小了一半(可优化调整)
Stop the world
在进行垃圾回收,枚举根节点的时候,对象之间的引用必须在一致性快照中(保证关系引用不能还是在变化的),如果不满足这点要求那么就无法保证,准确的回收垃圾.这就导致GC进行时必须停顿所有的java执行线程。停止java执行线程称为Stop the world。
安全点与安全区域
在进行GC的过程中,当执行系统停顿下来后,并不需要对上下文和全局的引用位置进行检索,而是可以直接找到那些地方存在对象的引用,通过一种OopMap的数据结构来实现,OopMap记录,栈和寄存器那些位置是应用。在生成本地代码时就插入一些记录Oomap指令记录对象引用
安全点
很多命令都可能导致引用的变化,不可能每执行一次这种指令就再记录一下OoMap,那么将会占用大量的额外空间,所以OoMap数据结构存储在一个特殊的点,这个存储的位置就是安全点,程序执行到达安全点停止,GC通过OoMap寻找垃圾,进行回收.
如何让所有线程都在安全点停下来?
主动式中断,设置一个标识,各个线程执行时不断轮询这个标志,发现标志时就自动挂起,轮询标志的地方和安全点重合。
安全区域
当线程处于Sleep状态或Blocked状态, 这时线程无法响应JVM的请求,走到安全点去中断.安全区域是指在一段代码片段之中,引用关系不会发生变化.在这个区域的任意位置开始GC都是安全的.
当线程执行到安全区域时候标识一下,这样在GC的时候就不管在安全区中的线程了,当线程要离开安全区的之前先检查一下GC是否完成,如果完成继续执行,否则等待完成再继续执行。
垃圾收集器
垃圾回收器适用区域与可用搭配如下:
Serial
新生代收集器 复制算法
单线程收集器,只使用一个cpu或一个线程,在清理过程中,其他工作线程暂停,Stop the world.简单而高效,在单个CPU情况下,由于没有多线程切换的开销,往往更高效.
Parnew
新生代收集器 复制算法
其实就是Serial的多线程版本
Parallel Scavenge
新生代收集器 复制算法
采用复制算法,才用多线程,它与Parnew的区别在于关注的点不同,Parallel Scavenge 目是达到一个可控制的吞吐量,保证用户代码运行时间
吞吐量= 运行用户代码时间/(运行用户代码时间+垃圾收集时间)
如果,虚拟机运行总时间为 100分钟, 运行客户代码时间为 99,垃圾回收为 1, 那么吞吐量就是 99%
常用可控参数
-XX:MaxGCPauseMillis (最大垃圾收集停顿时间,过小会到时频繁GC)
-XX:GCTimeRatio 大于0小于100的整数, 垃圾收集时间占总运行时间的比值.
-XX:UseAdaptiveSizePolicy 开关参数,打开后无需指定新生代大小,老年代大小,晋升老年代对象大小等细节参数,虚拟机根据系统运行情况自动调节
Serial Old
老年代收集器 使用标记整理算法
Serial 收集器的老年代版本, 使用单线程
Parallel Old
老年代收集器 使用标记整理
Paralle 的老年代版本多线程
CMS收集器
老年代收集器
Concurrent Mark Sweep, 以获取最短回收停顿时间为目标的收集器,基于标记整理实现
整理过程分为4个步骤:
- 初始化标记(CMS initial mark)
- 并发标记(CMS concurrent mark)
- 重新标记(CMS remark)
- 并发清除(CMS concurrent sweep)
初始化标记,重新标记任然需要 Stop the world
cmd 收集器三个特点:
- 对cpu资源非常敏感,在并发阶段,虽然不会停止用户线程,但是会因为占用了一些线程资源,导致应用变慢,总吞吐量降低.
- 无法处理浮动垃圾,在并发清理阶段,应用程序还会产生垃圾,这些垃圾是没有标记过的需要等到下一次gc才能清理,因此 cms 收集器不能等到老年区满了再开始回收,在到一定阈值时就开始回收1.6默认为92%,如果在清理期间内存不足,那么jvm会启动serial old收集器来收集,这样停顿的时间更长,所以需要合理的设置阈值
- 最后一个缺点,CMS基于标记清除,收集过会产生内存碎片,在CMS内存碎片过多时,JVM进行fullGC(清理整个堆)进行内存碎片整理,这个过程也将造成用户线程停顿
-XX:CMSInitiatingOccupancyFraction 设置阈值(老年区内存用到百分之多少进行垃圾回收)
G1收集器会单独再写一篇博客
咸鱼IT技术交流群:89248062,在这里有一群和你一样有爱、有追求、会生活的朋友! 大家在一起互相支持,共同陪伴,让自己每天都活在丰盛和喜乐中!同时还有庞大的小伙伴团体,在你遇到困扰时给予你及时的帮助,让你从自己的坑洞中快速爬出来,元气满满地重新投入到生活中
Java成神之路——JVM垃圾回收概览相关推荐
- Java成神之路技术整理
转载自 Java成神之路技术整理 以下是Java技术栈微信公众号发布的所有关于 Java 的技术干货,会从以下几个方面汇总,本文会长期更新. Java 基础篇 Java 集合篇 Java 多线程篇 J ...
- Java成神之路[转]
阿里大牛珍藏架构资料,点击链接免费获取 针对本文,博主最近在写<成神之路系列文章> ,分章分节介绍所有知识点.欢迎关注. 主要版本 更新时间 备注 v1.0 2015-08-01 首次发布 ...
- JVM内存区域(Java内存区域)、JVM垃圾回收机制(GC)初探
一.JVM内存区域(Java内存区域) 首先区分一下JVM内存区域(Java内存区域)和Java内存模型(JMM)的概念.Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Ja ...
- Alibaba技术专家倾心五年打造 Java成神之路:基础篇
近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是Java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考. ...
- 【深入理解Java虚拟机】读后感:JVM垃圾回收小结
JVM垃圾回收小结 1.GC 问题侧重点 虚拟机栈.本地方法栈.程序计数器随线程而生,随线程而灭.栈中的栈帧随方法的进入和退出而有条不紊地执行着出栈与入栈操作,每个栈帧分配多少内存基本是在类结构确定下 ...
- Java跨平台实现原理及JVM垃圾回收、内存管理实战
对象已死?啊,难受-- 最近深陷排查各种内存溢出.内存泄漏的问题,不得不对垃圾回收器下手了,因为当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些"自动化"的技术实施必要的 ...
- JVM成神之路-JVM内存结构
线程私有 程序计数器 当前线程所执行的字节码的行号指示器 对于 Java 方法,记录正在执行的虚拟机字节码指令的地址:对于 native 方法,记录值为空(Undefined) 唯一一个Java 虚拟 ...
- 【学海无涯】Java成神之路
基础篇 面向对象 面向对象与面向过程 面向过程就是按照程序进行的顺序依次编写索要完成相应任务的方法,依次调用.面型对象注重对逻辑概念的封装,将若干变量和方法封装成类,各个对象互相调用.面向对象占用 ...
- JVM成神之路-JVM引用模型
本文通过探析Java中的引用模型,分析比较强引用.软引用.弱引用.虚引用的概念及使用场景,知其然且知其所以然,希望给大家在实际开发实践.学习开源项目提供参考. Java的引用 对于Java中的垃圾回收 ...
最新文章
- 鸿蒙系统搁置,华为:我们将坚定的支持安卓生态,鸿蒙系统没有明确上市时间...
- 北斗导航 | ION GNSS+ 2021、 ION GNSS+ 2020会议论文下载:ION 美国导航学会
- 如何编写一份SOP?
- Method not found: '!!0[] System.Array.Empty()'.
- make的自动变量和预定义变量
- JavaScript 22岁生日快乐!
- PHP精美列表商城发卡网站源码响应式
- HashMap中,比较key是否相等为什么要重写equal() 和hashCode()这两个方法?
- Apowersoft ApowerMirror v1.4.5 终身商业授权破解版 安卓/iPhone投屏控制软件
- Windows系统重装教程完整版(系统备份、系统还原与重装)
- ArcGIS学习(一)——如何绘制一幅流域图
- 腾讯新闻 React 同构直出优化实践
- Linux学习1-Vmware创建虚拟机以及Xshell连接
- 秋冬季健康生活小常识
- 君明乐官,不明乐音。
- 计算机毕业设计springboot+uniapp点餐外卖系统源码
- 编程java摇号购房,用java编写摇号器
- PCB Layout爬电距离、电气间隙的确定
- scikit-learn 的设计
- 你告诉我,读书没有用