GC只需要回答三个问题:
本篇回答第一个问题
1、哪些对象需要回收?
答:针对的是方法区、堆。
堆的回收:
使用可达性分析算法来判断哪些对象需要进行回收。
可达性算法:选定GC Roots,对于对象到GC Roots没有可达路径的就是可被回收的。
什么对象可被选定为GC Roots:
注意GC Roots是一个集合,从这个集合里的对象去可达性分析,能达到的对象都是不可以被回收的,GC Roots里面的对象都是引用,都是活跃的引用!
GC Roots:我们只需要思考当前程序的运行,我们必须保证哪些对象必须存活即可。
以下四类组成的集合(然后做可达性分析(即为图遍历)),正好可以支撑当前程序运行。
a.虚拟机栈当前栈帧引用的对象,即局部变量表的引用。
b.方法区中类静态属性的引用(被static修饰的变量)。
c.方法区中常量的引用(被final修饰的变量)。
d.本地方法栈的栈帧中局部变量表的引用。
可达性分析后标记的对象:第一次标记不可达的对象,然后在这群对象里面将第一次执行finalize()方法的对象放入一个队列中,去执行这个方法(可能自救成功),第二次是队列的小规模标记。这时候,还被标记的对象就可以被GC了。 注意:实际开发中finalize()忽视掉,不要去使用它,所以在生产中,第一次被标记上的就是say goodbye的对象。
方法区中的回收:
回收常量:当没有一个引用使用这个常量的时候,被回收。(判断方式与收集对象类似)
回收类:回收不是必要的,可用参数来指定是否对无用类进行回收。
什么是无用类?
1.没有该类的实例对象了。
2.加载该类的ClassLoader被回收了
3.该类的Class对象没有被引用,无法通过反射访问该类的方法。
知识点:引用
很纯粹的引用定义:如果reference类型的数据的值是内存地址,那么这就是一个引用。
现代Java的引用分为了好几类:
一篇好文讲解Java中的引用:Java引用说明
设计目的:满足当内存充足的时候对某些对象不进行回收,当内存不足的时候对某些对象进行回收的场景。比如:缓存的设计。
强引用:new出来的对象。宁愿OOM也不远被回收。
软引用:内存不足的时候被回收。使用SoftReference API来定义。使用场景:缓存,当内存不足时,JVM自动进行回收。
弱引用:无论内存是否充足,只要发生GC,就会回收被WeakReference引用关联的对象。(当只有弱引用时,只要GC就一定会被回收)
虚引用:作用,标志这虚引用关联的对象是否要被回收了。作用机理就是:当准备回收这个对象当时候,将虚引用加入到引用的关联队列中。我们可以根据引用队列中有该虚引用,来对即将要被回收的该对象做前置动作。
2、什么时候进行回收?
答:MinorGC,Full GC。
3、如何进行回收?
答:垃圾回收算法。