面试问题:
判断一个对象是否可用,GC回收对象的过程方式,finilized函数了解吗,调用了finilized函数的对象一定会被回收吗,可以主动调用finilized函数吗?
判断一个对象是否可用:
根搜索算法,引用计数法(循环引用,js使用)
JVM使用的根搜索算法(引自深入理解JVM):
一个对象到GC Roots没有任何引用链相连,则该对象不可用,这时Java虚拟机可以对这些对象进行回收。
Java虚拟机将以下对象定义为 GC Roots :
- Java虚拟机栈中引用的对象,虚拟机栈中(栈帧)
- 静态属性引用的对象,static对象
- 常量引用的对象,final对象
- 本地方法栈中引用的对象,nio
finilized函数是遗留产出,和C++的析构函数有本质区别,调用了finilized函数对象不一定会被回收,finilized函数也不是每次必会被调用。一般回收对象会调用这个函数,但我们不必重写这个函数因为Object中已经实现了一个空的finilized。
protected void finalize() throws Throwable { }
finilized函数执行的大致过程:
当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。
否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。
执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。
Java中的finalize的调用具有不确定性,就是说何时调用(调用时机)是不确定的,JVM也不保证一定会被调用。
子类可以实现这个方法做一些回收资源的操作。
可以主动调用finilized函数吗?
finalize()可以主动调用, 但不建议调用, 由于gc也会调用可能会发生某种异常导致资源释放出现问题。