深入分析JVM:Java垃圾收集算法+常用垃圾收集器解析

推荐学习

  • “吃”完这本Java性能调优实战 , MySQL+JVM+Tomcat等问题一键全消
  • 死磕「并发编程」100天 , 全靠阿里大牛的这份最全「高并发套餐」
如何确定无效对象在垃圾收集的时候第一件事就是怎么确定一个对象是垃圾 , 那么该如何确定一个对象已经可以被回收了呢?主流的算法有两种:引用计数法和可达性分析算法
引用计数法(Reference Counting)这个算法很简单 , 效率也非常高 。 就是给每个对象添加一个引用计数器 , 每当有一个地方引用它时 , 计数器的值就加1 , 当引用失效时 , 计数器的值就减1 , 当计数器的值减为0时就表名这个对象不会再被使用 , 成为了无用对象 , 可以被回收 。
这种算法虽然实现简单 , 效率也高 , 但是存在一个问题 , 我们看下面一个场景:
深入分析JVM:Java垃圾收集算法+常用垃圾收集器解析文章插图
上图中4个对象相互引用 , 但是并没有其他对象去引用他们 , 这种对象实际上也是无效对象 , 但是他们的引用计数器都是1而不是0 , 所以引用计数法没办法解决这种“一坨垃圾”的场景 。
可达性分析算法(Reachability Analysis)可达性分析算法就是选择一些对象作为起始点 , 这些对象称之为:GC Root 。 然后从GC Root开始向下搜索 , 搜索路径称之为引用链(Reference Chain) , 当一个对象不在任何一条引用链上时 , 就说明此对象是无效对象 , 可以被回收 。 比如说下面这幅图 , 右边那一串互相引用的对象因为没有不在GC Root的引用链上 , 所以就是无效对象 , 可达性分析算法有效的解决了互相引用对象无法回收问题 。
深入分析JVM:Java垃圾收集算法+常用垃圾收集器解析文章插图
GC Root在Java中 , 可以作为GC Root对象的包括下面几种:
  • Java虚拟机栈内栈帧中的局部变量表中的变量
  • 方法区中类静态属性
  • 方法区中常量
  • 本地方法栈中JNI(即Native方法)中的变量
注意:在分析对象的过程中 , 为了确保结果的准确性 , 需要保证分析过程中对象引用关系不会发生变化 , 而为了达到这个目的 , 就需要暂停用户线程 , 这种操作也叫:Stop The World(STW) 。
引用的分类上面两种算法其实都是一个目的 , 判断对象有没有被引用 , 而引用也不仅仅都是一样的引用 , JDK1.2开始 , Java中将引用进行了分类 , 划分成了四种引用 , 分别是:强引用 , 软引用 , 弱引用 , 虚引用 。 这四种引用关系的强度为:强引用>软引用>弱引用>虚引用 。
强引用(Strong Reference)我们写的代码中一般都是用的强引用 , 如:Object obj = new Object()这种就属与强引用 , 强引用只要还存在 , 一定不会被回收 , 空间不够就直接抛出OOM异常
软引用(Soft Reference)软引用是通过SoftReference类来实现的 。 软引用可以用来表示一些还有用但又是非必需的对象 , 系统在即将溢出之前 , 如果发现有软引用的对象存在 , 会对其进行二次回收 , 回收之后内存还是不够 , 就会抛出OOM异常 。
弱引用(Weak Reference)弱引用是通过WeakReference类来实现的 。 弱引用也是用来表示非必需对象的 , 但是相比较软引用 , 弱引用的对象会在第一次垃圾回收的时候就被回收掉 。
虚引用(Phantom Reference)虚引用是通过PhantomReference类来实现的 , 也被成为幽灵引用或者幻影引用 。 这是最弱的一种引用关系 。 一个对象是否有虚引用的存在 , 完全不对其生存时间构成影响 。 也无法通过虚引用来取得一个对象实例 。 设置为虚引用的唯一用处可能就是当这个对象被回收的时候可以收到一个系统通知 。
垃圾收集算法上面分析了如何确定一个对象属于可回收对象的两种算法 , 那么当一个对象被确定为垃圾之后 , 就需要对其进行回收 , 回收也有不同的算法 , 下面就来看一下常用的垃圾收集算法
标记-清除(Mark-Sweep)算法标记-清除算法主要分为两步 , 标记(Mark)和清除(Sweep) 。 比如说有下面一块内存区域(白色-未使用 , 灰色-无引用 , 蓝色-有引用):
深入分析JVM:Java垃圾收集算法+常用垃圾收集器解析文章插图
然后标记-清除算法会进行如下两个步骤:
  • 1、将堆内存扫描一遍 , 然后会把灰色的区域(无引用对象 , 可被回收)对象标记一下 。
  • 2、继续扫描 , 扫描的同时将被标记的对象进行统一回收 。
标记清除之后得到如下图所示:
深入分析JVM:Java垃圾收集算法+常用垃圾收集器解析文章插图