就在移除一个对象并回收它的内存空间之前,Java垃圾回收器将会调用各个实例的finalize()方法,这样实例对象就有机会可以释放掉它占用的资源。尽管finalize()方法是保证在回收内存空间之前执行的,但是对具体的执行时间和执行顺序是没有任何保证的。多个实例之间的finalize()执行顺序是不能提前预知的,甚至有可能它们是并行执行的。程序不应该预先假设实例执行finalize()的方法,也不应该使用finalize()方法来回收资源。
这个主要考察答题者是否了解 GC对不可用对象的判断过程,大家不要只是去了解finalize()方法,这样容易感到迷惑,如果这个题答不上来,最好还是去了解一下GC对哪些内存进行了回收以及对不可用对象的判断。
下面是 “ GC对哪些内存进行了回收 ” 的一个简单的回答:
gc是对不可用的对象进行回收,判断一个对象是否不可用采用的是可达性分析算法,具体的做法就是:从“GC Roots”开始,向下搜索,如果从GC Roots到某个对象不可达,那么这个对象就是不可用的,会被判定为是可回收的对象。
不过这些对象也不是立即就会被回收,真正宣告一个对象死亡需要至少经历两次标记过程。
在Java虚拟机的垃圾回收器看来,堆区中的每个对象都可能处于以下三个状态之一。
可触及状态:当一个对象(假定为Sample对象)被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。
可复活状态:当程序不再有任何引用变量引用Sample对象时,它就进入可复活状态。在这个状态中,垃圾回收器会准备释放它占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的finalize()方法,这些finalize()方法有可能使Sample
对象重新转到可触及状态。
不可触及状态:当Java虚拟机执行完所有可复活对象的finalize()方法后,假如这些方法都没有使Sample对象转到可触及状态,那么Sample对象就进入不可触及状态。只有当对象处于不可触及状态时,垃圾回收器才会真正回收它占用的内存。
notify唤醒线程,与wait()和同步锁synchronized()方法配合使用
就在移除一个对象并回收它的内存空间之前,Java垃圾回收器将会调用各个实例的finalize()方法,这样实例对象就有机会可以释放掉它占用的资源。尽管finalize()方法是保证在回收内存空间之前执行的,但是对具体的执行时间和执行顺序是没有任何保证的。多个实例之间的finalize()执行顺序是不能提前预知的,甚至有可能它们是并行执行的。程序不应该预先假设实例执行finalize()的方法,也不应该使用finalize()方法来回收资源。