java.lang.ref.FinalizerReference引发的内存泄漏

来源:互联网 发布:淘宝主页设计 编辑:程序博客网 时间:2024/05/20 06:55

这和GC的机制有关:

实现了object的finalize()的类在创建时会新建一个FinalizerReference,这个对象是强引用类型,封装了override  finalize()的对象,下面直接叫原对象。原对象没有被其他对象引用时(FinalizeReference除外),执行GC不会马上被清除掉,而是放入一个静态链表中(ReferenceQueue),有一个守护线程专门去维护这个链表,如何维护呢?就是轮到该线程执行时就弹出里面的对象,执行它们的finalize(),对应的FinalizerReference对象在下次执行GC时就会被清理掉。
一个堆的FinalizerReference会组成一条双向链表,垃圾回收器应该会持有链表头(链表头在FinalizerReference中为一个静态成员)。

为什么会泄漏:

直接原因就是守护线程优先级比较低,运行的时间比较少。如果较短时间内创建较多的原对象,就会因为守护线程来不及弹出原对象而使FinalizerReference和原对象都得不到回收。无论怎样调用GC都没有用的,因为只要原对象没有被守护线程弹出执行其finalize()方法,FinalizerReference对象就不会被GC回收。


知道这些机制后,应该注意以下几点:

1.  紧缺资源不要依赖finalize()来释放。

2.  尽量不要重载finalize()。

3.  如果必须重载finalize(),一定要记得调用super.finalize,也建议把类实现成单例模式(减少FinalizerReference占用)。



http://blog.csdn.net/gwgking2012/article/details/41278949

http://www.oschina.net/question/12_19310

http://it.deepinmind.com/gc/2014/05/13/debugging-to-understand-finalizer.html

0 0
原创粉丝点击