CSDN|超详解读:垃圾回收机制 | 原力计划


CSDN|超详解读:垃圾回收机制 | 原力计划
本文插图
作者 | zycxnanwang 责编 | 王晓曼 出品 | CSDN博客判断对象是否存活的方法1、引用计数法每个对象上都有一个引用计数 , 对象每被引用一次 , 引用计数器就+1 , 对象引用被释放 , 引用计数器-1 , 直到对象的引用计数为0 , 对象就标识可以回收 。 但是这个算法有明显的缺陷 , 对于循环引用的情况下 , 循环引用的对象就不会被回收 。实例:public class ReferenceCountingGC{ public Object instance = null; private static final int _1MB = 1024 * 1024; private byte bigSize = new byte[2 * _1MB]; public static void testGC { ReferenceCountingGC objA = new ReferenceCountingGC; ReferenceCountingGC objB = new objA.instance = objB; objB.instance = objA; objA = null; objB = null; System.gc; }}//发生嵌套引用 , 但是在java中 , objA和objB的内存可以被回收2、可达性分析算法基本思路是:通过一系列的称为“GC Roots”的对象作为起始点 , 从这些节点开始向下探索 , 搜索所走过的路径称为“引用链” , 当一个对象到GC Roots没有任何引用链相连(用图论的话来说 , 就是从GC Roots到这个对象不可达)时 , 则证明此对象是不可用的 。 在Java语言中 , 可作为GC Roots的对象包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  • 方法区中类静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象 。
CSDN|超详解读:垃圾回收机制 | 原力计划
本文插图
3、引用类型(1)强引用强引用就是指在程序代码之中普遍存在的 , 类似“Object obj = new Object’'这类的引用 , 只要强引用存在 , 垃圾收集器永远不会回收掉被引用的对象 。(2)软引用软引用用来描述一些还有用但并非必须的对象 。 对于软引用关联着的对象 , 在系统将要发生内存溢出异常之前 , 将会把这些对象列进回收范围之中进行第二次回收 。 如果这次还没有足够的内存 , 才会抛出内存溢出异常 。(3)弱引用弱引用也是用来描述非必须对象 , 但是它的强度比软引用更弱一些 , 被弱引用关联的对象只能生存到下一次垃圾收集发生之前 。 当垃圾收集器工作时 , 无论当前内存是否足够 , 都会回收掉只被弱引用关联的对象 。(4)虚引用虚引用也称为幽灵引用或者幻影引用 , 它是最弱的一种引用关系 。 一个对象是否有虚引用的存在 , 完全不会对其生存时间构成影响 , 也无法通过虚引用来取得一个对象实例 。 为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知 。4、对象是否一定要清除假设在可达性分析算法中某个对象不可达 , 它也并非”非死不可” 。 如果这个对象覆盖了finalize方法且这个方法没有被JVM调用过 , 则JVM会执行finalize方法 。 这时你可以在这个方法中重新使某个引用指向该对象 。 当然 , finalize方法只能救它一次 。垃圾回收算法1、标记-清除(Mark-Sweep)算法最基础的垃圾回收算法 , 分为两个阶段 , 标记和清除 。 标记阶段标记出所有需要回收的对象 , 清除阶段回收被标记的对象所占用的空间 。 从图中我们就可以发现 , 该算法最大的问题是内存碎片化严重 , 后续可能发生大对象不能找到可利用空间的问题 。CSDN|超详解读:垃圾回收机制 | 原力计划
本文插图
2、标记整理(Mark-Compact)算法标记阶段和Mark-Sweep算法相同 , 标记后不是清理对象 , 而是将存活对象移向内存的一端 。 然后清除端边界外的对象 。【CSDN|超详解读:垃圾回收机制 | 原力计划】


推荐阅读