深入分析JVM:Java垃圾收集算法+常用垃圾收集器解析
推荐学习
- “吃”完这本Java性能调优实战 , MySQL+JVM+Tomcat等问题一键全消
- 死磕「并发编程」100天 , 全靠阿里大牛的这份最全「高并发套餐」
引用计数法(Reference Counting)这个算法很简单 , 效率也非常高 。 就是给每个对象添加一个引用计数器 , 每当有一个地方引用它时 , 计数器的值就加1 , 当引用失效时 , 计数器的值就减1 , 当计数器的值减为0时就表名这个对象不会再被使用 , 成为了无用对象 , 可以被回收 。
这种算法虽然实现简单 , 效率也高 , 但是存在一个问题 , 我们看下面一个场景:
文章插图上图中4个对象相互引用 , 但是并没有其他对象去引用他们 , 这种对象实际上也是无效对象 , 但是他们的引用计数器都是1而不是0 , 所以引用计数法没办法解决这种“一坨垃圾”的场景 。
可达性分析算法(Reachability Analysis)可达性分析算法就是选择一些对象作为起始点 , 这些对象称之为:GC Root 。 然后从GC Root开始向下搜索 , 搜索路径称之为引用链(Reference Chain) , 当一个对象不在任何一条引用链上时 , 就说明此对象是无效对象 , 可以被回收 。 比如说下面这幅图 , 右边那一串互相引用的对象因为没有不在GC Root的引用链上 , 所以就是无效对象 , 可达性分析算法有效的解决了互相引用对象无法回收问题 。
文章插图GC Root在Java中 , 可以作为GC Root对象的包括下面几种:
- Java虚拟机栈内栈帧中的局部变量表中的变量
- 方法区中类静态属性
- 方法区中常量
- 本地方法栈中JNI(即Native方法)中的变量
引用的分类上面两种算法其实都是一个目的 , 判断对象有没有被引用 , 而引用也不仅仅都是一样的引用 , JDK1.2开始 , Java中将引用进行了分类 , 划分成了四种引用 , 分别是:强引用 , 软引用 , 弱引用 , 虚引用 。 这四种引用关系的强度为:强引用>软引用>弱引用>虚引用 。
强引用(Strong Reference)我们写的代码中一般都是用的强引用 , 如:Object obj = new Object()这种就属与强引用 , 强引用只要还存在 , 一定不会被回收 , 空间不够就直接抛出OOM异常
软引用(Soft Reference)软引用是通过SoftReference类来实现的 。 软引用可以用来表示一些还有用但又是非必需的对象 , 系统在即将溢出之前 , 如果发现有软引用的对象存在 , 会对其进行二次回收 , 回收之后内存还是不够 , 就会抛出OOM异常 。
弱引用(Weak Reference)弱引用是通过WeakReference类来实现的 。 弱引用也是用来表示非必需对象的 , 但是相比较软引用 , 弱引用的对象会在第一次垃圾回收的时候就被回收掉 。
虚引用(Phantom Reference)虚引用是通过PhantomReference类来实现的 , 也被成为幽灵引用或者幻影引用 。 这是最弱的一种引用关系 。 一个对象是否有虚引用的存在 , 完全不对其生存时间构成影响 。 也无法通过虚引用来取得一个对象实例 。 设置为虚引用的唯一用处可能就是当这个对象被回收的时候可以收到一个系统通知 。
垃圾收集算法上面分析了如何确定一个对象属于可回收对象的两种算法 , 那么当一个对象被确定为垃圾之后 , 就需要对其进行回收 , 回收也有不同的算法 , 下面就来看一下常用的垃圾收集算法
标记-清除(Mark-Sweep)算法标记-清除算法主要分为两步 , 标记(Mark)和清除(Sweep) 。 比如说有下面一块内存区域(白色-未使用 , 灰色-无引用 , 蓝色-有引用):
文章插图然后标记-清除算法会进行如下两个步骤:
- 1、将堆内存扫描一遍 , 然后会把灰色的区域(无引用对象 , 可被回收)对象标记一下 。
- 2、继续扫描 , 扫描的同时将被标记的对象进行统一回收 。
文章插图
- 现状|程序员现状揭秘:平均年薪20.36万,Java人才需求量最大
- 程序员学英语第1天——JavaScript 程序测试的介绍1
- 三年Java开发,刚从美团、京东、阿里面试归来,分享个人面经
- 《深入理解Java虚拟机》:对象创建、布局和访问全过程
- java面试题整理
- Kotlin集合vs Kotlin序列与Java流
- Java安全之Javassist动态编程
- 推荐Java工程师必看,12个Hadoop领域的上手项目
- 震惊!京东T4大佬面试整整三个月,才写了两份java面试笔记
- 整理:常见的Java开发框架有哪些,看过,就赶紧收藏吧
