Java 中垃圾回收 中的内容比较多,我们这里在做总结的时候,分为上下两篇,即
JVM_JVM 垃圾回收的基本策略 (GC 上篇)
JVM_Java 中常见的几种垃圾回收器 (GC 下篇)
本篇,我们会去介绍下2个方面
1.判断对象是否要回收
2.对象的垃圾回收策略
判断对象是否要回收
判断对象是否要回收目前主要有2种策略,引用计数法 与 可达性分析算法。
Java 中目前判断对象是否要回收使用的是可达性分析算法。
引用计数法
引用计数法的规则十分简单,主要的思路如下 :
给对象增加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。
引用计数法的一些应用案例
微软的COM (Component Object Model) 技术,使用 ActionScript 3 的 FlashPlayer, Python 语言 和 在游戏脚本领域被广泛应用的 Squirrel 都使用了引用计数算法 进行内存管理。
Java 没有采用引用计数法的原因
Java 虚拟机里面没有选用引用计数法来管理内存,最主要的原因是他很难解决对象之前相互循环引用的问题。
可达性分析算法
可达性分析算法的实现思路如下:
这个算法的基本思路 通过一系列 称为 ”GC Roots“ 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到 GC Roots 没有任何引用链相连时,则证明该对象是不可用的。
可达性分析的实际案例
在主流的商业程序语言(Java, C# 甚至包括前面提到的古老的 Lisp)的主流实现中,都是通过可达性分析 (Reachability Analysis)来判定对象是否存活的。
可作为 GC Roots 的对象包括以下几种
1.虚拟机栈(帧栈中的本地变量表)中引用的对象。
2.方法区中类静态属性引用的对象。
3.方法区中常量引用的对象
4.本地方法栈中JNI (即一般说的Native 方法) 引用的对象
Java 中额外的部分:
判断对象的存活 与 ”引用” 有关。Java 中有4类引用。主要有以下几种
强引用(Strong Reference),软引用 (Soft Reference), 弱引用 (Weak Reference), 虚引用 (Phantom Reference)4种。
强引用 就是指程序代码中普遍存在的 ,类似 Object obj = new Object() 这类引用, 只要强引用还在,垃圾收集器永远不会回收掉被引用的对象
软引用 是用来描述一些还有用但并非必要的对象。对于软引用关联着的对象,在系统将要发生内存溢出之前,将会把这些对象列进回收范围之中进行二次回收,如果 这次回收还没足够空间,才会抛出内存溢出异常。
弱引用 也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存道下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
虚引用 也称为幽灵引用或者幻影引用,他是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。
为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
对象的垃圾回收策略