垃圾收集器与内存分配策略(一)
1.判断对象是否存活
a.计数器算法
算法描述:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器值减1;任何时刻计数器为0的对象就是不可能再被使用的。
该算法实现简单,效率也很高,但是Java虚拟机中没有使用计数器算法来管理内存,主要原因就是它很难解决对象之间相互循环引用的问题。
b.可达性分析算法
算法描述:通过一系列的称为"GC Roots"的对象作为起点,从这些节点开始向下进行搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连,换句话说,从GC Roots到该对象不可达时,则说明该对象是不可用的。
Java语言中可以选做GC Roots的对象:虚拟机栈中引用的对象;方法区中类静态属性引用的对象;方法区中常量引用的对象;本地方法栈中JNI(即一般说的Native方法)引用的对象。
2. 再谈引用
JDK1.2之后,Java将引用分为强引用、软引用、弱引用和虚引用四种。
强引用:只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象;
软引用:描述了还有用但是非必需的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收;
弱引用:描述了非必需对象,被弱引用关联的对象只能生存到下一次垃圾回收之前;
虚引用:为对象设置该引用的唯一目的就是能在这个对象被垃圾收集器回收时收到一个系统通知。
3.回收方法区
方法区垃圾收集主要回收两部分内容:废弃常量和无用的类。
回收废弃常量与回收Java堆中的对象非常类似,当该常量没有任何引用时就是废弃常量。
无用的类需要满足以下三个条件:
该类所有实例均被回收,即Java堆上不存在该类的任何实例;
加载该类的ClassLoader已经被回收;
该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
无用的类仅仅是可以被回收,并不一定必然被回收。