1 检测对象是否存活
1.1 引用计数法
1.2 可达性分析法
Java中作为 GC Roots 的对象包括下面几种:
虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中 JNI 引用的对象。
1.3 引用分类
强度依次减弱:
- 强引用(Strong Reference)
永远不会被垃圾回收器回收的。
- 软引用(Soft Reference)
将要发生 OOM 时,GC回收。
- 弱引用 (Weak Reference)
被弱引用关联的对象只能生存到下一次 GC 之前。GC 回收时,弱引用会被回收。
- 虚引用(Phantom Reference)
在这个对象被 GC 回收时收到一个系统通知。
1.4 对象回收经过2次检测
finalize() 方法
F-Queue 队列,稍后由虚拟机自动建立、低优先级的 Finalizer 线程去执行
1.5 方法区回收
回收对象:废弃常量和无用的类
判定类是无用类:
该类所有的实例都被回收,也就是 Java 堆中不存在该类的任何实例。
加载该类的 ClassLoader 已经被回收。
该类对应的 java.lang.Class 对象没有任何地方被引用,无法再任何地方通过反射访问该类的方法。
2 垃圾回收算法
-
标记-清除算法
-
复制算法
- 新生代使用此算法
- 分为三片区域 8:1:1(Eden和2个Survivor)
-
标记-整理算法
-分代收集算法
现在的虚拟机都采用分代收集算法,新生代采用复制算法,老年代采用“标记-清除”或者“标记-整理”算法。
3 内存分配与回收策略
对象优先在 Eden 分配
大对象直接进入老年代
长期存活的对象将进入老年代
虚拟机给每个对象定义一个对象年龄(Age)计数器,对象经过 Eden 出生并经过第一次 Minor GC 后仍然存活,并且能被 Survivor 容纳,将被移动到 Survivor,并且对象年龄设置为1。
对象在 Survivor 区经过一次 Minor GC,年龄就加1,当年龄达到一定值(默认15)时,移到老年代中。