对象判活
垃圾收集首先需要判断一个对象是否是”活”的,一般有两种算法:1 引用计数:为每个对象加一个计数器,每次引用加一,实现简单,效率高,但是不能解决循环引用;2 可达性分析:通过判断一个对象是否可达来确定是否为活,目前一些语言的主流实现。可达性分析
可达性分析即从GC Root对象开始,向下搜索,搜索路径称为引用链,当一个对象不能从任何GC Root对象到达时,则证明此对象不可用。
GC Root对象包括:
1 虚拟机栈帧中的本地变量表中引用的对象
2 方法区中静态属性引用的对象
3 方法区中常量引用的对象
4 本地方法栈即native方法中引用的对象引用种类
强引用:一般使用的引用,强引用指向的对象不会被回收,只要强引用还存在的话。
软引用:一般不回收,发生内存溢出时回收
弱引用:生存到下一次垃圾回收,无论内存是否紧张
虚引用:不会影响对象的生存周期,也无法取得对象,只是回收时能收到通知回收过程
回收时首先判断是否有必要执行finalize方法,判断条件是finalize方法是否被覆盖,是否被执行过了。
如果没有覆盖或已经执行过了,就直接回收。如果覆盖了或没执行过,就加入到一个队列,稍后在一个虚拟机建立的finalize线程一个个执行,然后第二遍的话,如果finalize方法中没有跟GC Root对象连上,就真的回收了。方法区回收
方法区主要回收废弃常量和废弃类,没有任何地方用到的常量,即废弃常量;一个类的所有实例被回收,加载这个类的classloader被回收,并且没有这个类的Class对象来反射它,那么这个类就是废弃类。垃圾回收算法
- 标记清除算法:先标记需要回收的对象,然后回收。效率低,空间产生碎片多。
- 复制法:把堆分成两部分,或多部分,再一部分里生产对象,回收时把存活的放到另外部分,其余全清了
- 标记整理法:先标记不用清理的,然后把它们从开头的地方一个个对其过去,对齐边界外的全部清除
- 分代收集法:根据不同代的特点使用不同算法,少量存活的区就复制法,死亡率少的,就标记清除,或标记整理。
理论方面大概就这些