1. 判断对象是否可以进行回收
1.1 引用计数算法
定义 : 为对象添加一个引用计数器, 每当有一个地方引用它,计数器值就加一, 当引用失效时, 计数器值就减一.
优点 : 实现简单, 效率高
缺点 : 很难解决对象之间相互循环引用的问题
1.2 可达性分析算法
基本思想 : 通过一系列称为"GC Roots"的对象作为起始点, 从这些节点向下搜索, 搜索走过的路径称为引用链, 当一个对象到GC Roots 没有任何引用链相连时, 则此对象是不可用的.
GC Roots :
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(Native方法)引用的对象
引用类型 :
- 強引用 : 类似于 Object obj = new Object() 的这类引用, GC不会回收强引用引用的对象
- 软引用 : 描述一些还有用但是非必需的对象, 在系统发生内存溢出异常之前, 会把这些对象列进回收范围进行二次回收. SoftReference类来实现软引用
- 弱引用 : 描述非必需对象. 此类对象只能生存到下一次垃圾回收之前. 垃圾回收时, 无论当前内存是否足够, 都会回收掉只被弱引用关联的对象. WeakReference类实现弱引用
- 虚引用 : 唯一目的是在对象被回收时收到一个系统通知.
1.3 对象的回收
当对象可达性分析后为被判断为回收对象时, 会进行第一次标记, 并判断此对象有无必要执行finalize().
没有必要:
a. 对象未覆盖finalize()
b. 虚拟机已经调用过finalize()
有必要 :
对象被放置在F-Quene队列中, 稍后虚拟机自动建立低优先级的Finalizer线程去执行它的finalize()(并不承诺等待他运行结束,可能发生死循环), 稍后对队列中的对象进行第二次小规模的标记, 之后就会被真正回收.
对象可在finalize()中拯救自己, 重新与引用链上的对象建立关联
任何对象的finalize()只会被系统调用一次
2. 回收方法区
主要回收废弃的常量和无用的类.
2.1 废弃的常量
- 没有任何地方引用该常量时即可回收它.
2.2 无用的类
- 该类的所有实例都已经被回收, Java堆中不存在任何该类的实例
- 加载该类的ClassLoder已经被回收
- 该类的Class对象没有在任何地方被引用, 无法在任何地方通过反射访问该类的方法