1、引用计数器
2、可达性分析 GC Root:
Java语言中,可做为GC Root的对象有以下几种:
虚拟机栈中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
3、引用:
强引用(Strong Reference):类似“Object obj = new Object()”,只要强引用存在,垃圾收集器就永远不会回收掉被引用的对象。
软引用(Soft Reference):软引用用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收。如果这次回收后还没有足够的内存,才会抛出内存溢出异常。
弱引用(Weak Reference):弱引用是用来描述非必需对象的,它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
虚引用(Phantom Reference):虚引用也称为幽灵引用或幻影引用,他是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用的唯一目的就是在这个对象被收集器回收时收到一个系统通知。
4、回收方法区:
主要回收废弃的常量和无用的类。没有其他地方引用这个常量,有必要的话这个常量会被GC清除。一个类同时满足:该类所有的的实例已经被回收,也就是Java堆中不存在任何该类的实例;加载该类的ClassLoader已经被回收;该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的的方法;在大量使用CGLib、动态代理、反射等场景下都需要虚拟机具备类卸载能力,以保证永久代不会溢出。
5、垃圾回收算法:
标记-清除算法:
首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。它的主要不足有两个,效率问题:标记和清理的过程效率都不高;标记清除后会产生大量的内存碎片,当后续需要分配较大的对象时,没有足够的连续空间,不得不提前触发另一次垃圾收集动作。
复制算法:
将内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块内存用完了就将这一块内存上面还存活的对象复制到另一块内存区域上,然后再把已经使用过的内存空间一次性清理掉。现在的商业虚拟机中都使用这种算法回收新生代内存区域。
标记-整理算法:
标记出需要回收的对象,让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。
分代收集算法:
Java堆分为新生代和老年代。在新生代中每次都有大批的对象死去,只有少量存活,选用复制算法。老年代中因为对象存活率高,没有额外控件对它进行分配担保,使用“标记-清除”或“标记-整理”算法。
摘自 《深入理解Java虚拟机》