平时我们系统运行创建的对象都是优先分配在新生代里的,如果新生代里的对象越来越多,都快满了,此时就会触发垃圾回收,把新生代没有人引用的对象给回收掉,释放内存空间,这就是新生代一个核心的垃圾回收触发时机。

1.被哪些变量引用的对象是不能回收的?

一旦新生代快满了,那么垃圾回收的时候,到底哪些对象是能回收的,哪些对象是不能回收的呢?
JVM中使用了一种可达性分析算法来判定哪些对象是可以被回收的,哪些对象是不可以被回收的。这个算法的意思,就是说对每个对象,都分析一下有谁在引用他,然后一层一层往上去判断,看是否有一个GC Roots。
在JVM规范中,局部变量就是可以作为GC Roots的,只要一个对象被局部变量引用了,那么就说明他有一个GC Roots,此时就不能被回收了。
在JVM的规范里,静态变量也可以看做是一种GC Roots,此时只要一个对象被GC Roots引用了,就不会去回收他。
只要你的对象被方法的局部变量、类的静态变量给引用了,就不会回收他们。

2.Java中对象不同的引用类型

强引用、软引用、弱引用和虚引用;
只要是强引用的类型,那么垃圾回收的时候绝对不会去回收这个对象的。正常情况下垃圾回收是不会回收软引用对象的,但是如果你进行垃圾回收之后,发现内存空间还是不够存放新的对象,内存都快溢出了,此时就会把这些软引用对象给回收掉,哪怕他被变量引用了,但是因为他是软引用,所以还是要回收。弱引用就跟没引用是类似的,如果发生垃圾回收,就会把这个对象回收掉。虚引用,暂时忽略,因为很少用。

3.finalize()方法的作用

有GC Roots引用的对象不能回收,没有GC Roots引用的对象可以回收,如果有GC Roots引用,但是如果是软引用或者弱引用的,也有可能被回收掉。
假设没有GC Roots引用的对象,是一定立马被回收吗?其实不是的,这里有一个finalize()方法可以拯救他自己。如果重新让某个GC Roots变量引用了自己,那么就不用被垃圾回收了。