它是Object中的一个方法,子类重写它,垃圾回收时此方法会被调用,可以在其中进行一些资源释放和清理工作,但将资源释放和清理放在finalize方法中非常不友好,非常影响性能,严重时甚至会引起OOM,从java9开始就被标注为@Deprecated,不建议被使用。
为什么finalize方法非常不好,非常影响性能?
1. 非常不好
- FinalizerThread是守护线程,代码很有可能没来得及执行完,线程就结束了,造成资源没有正确释放。
- 异常会被吞掉,不能判断有没有在释放资源时发生错误。
2. 影响性能
- 重写了finalize方法的对象在第一次被GC时,并不能及时释放它占用的内存,因为要等着FinalizerThread调用完finalize,把它从第一个unfinalized队列移除后,第二次GC时才能真正释放内存。
- GC本就因为内存不足引起,finalize调用又很慢(两个队列的移除操作,都是串行执行的,用来释放连接类的资源应该也不快),不能及时释放内存,对象释放不及时就会逐渐移入老年代,老年代垃圾积累过多就会容易Full GC,Full GC释放速度如果仍跟不上创建新对象的速度,就会OOM。
3. 问题
有的文章提到【Finalizer线程会和我们的主线程进行竞争,不过由于它的优先级较低,获取到的CPU时间较少,因此它永远也赶不上主线程的步伐】,这个显然是错误的,FinalizerThread的优先级较普通线程高,赶不上步伐的原因应该是finalize执行慢等原因导致的。