今天遇到一个bug,一个方法中new一个局部变量 a,这个a以WeakReference的方式被其他地方调用。然后我在运行中,经常发现a中代码无法执行。
问题分析:为什么a中的代码无法执行?
1、代码逻辑有问题,未执行到a时,方法就已经return或者throw exception了。
2、考虑到使用的是WeakReference,该对象有可能在执行之前已经被回收。
3、还未想到有什么其他原因……
原因排除:
通过打印日志和单步调试,发现代码逻辑上没有任何问题,那么只剩下一个原因,该对象a已经被回收。通过重载finalize()方法打印日志验证,a对象在被执行之前就已经被回收了。
解决办法:
对象a之所以被回收,肯定是因为使用的WeakReference对其进行调用导致系统随时可能进行回收,我暂时还不知道系统因为什么原因将其回收,但是我并不关心这个,我关心的是如何防止其被回收。出于代码和业务原因,无法更改WeakReference的使用方式,那么只能通过其他方式防止该对象被回收。解决方式如下:
由于a所在的方法为静态方法,所以我直接将a创建为类中的静态成员,在方法执行时,对a进行临时创建。这样由于a是静态成员,常驻内存,所以不会因为它被WeakReference方式引用而容易导致被回收。到此问题解决。
经验心得:
之前也看过一些关于WeakReference的知识,只是基本没用过,对其中的概念也不是特别明朗。通过这个问题的处理,我更加明白Java垃圾回收机制的原理,当一个对象没有被引用时,那么它就可能被回收,如果只有一个引用,而这个引用又不是强引用,那么它也有可能随时被回收。所以如果要防止一个对象被回收,那么有两种方式:
1、始终持有该对象的强引用,只要该对象被引用,那么Java的垃圾回收器就基本不会对其回收。
2、让该对象成为静态对象,常驻内存,对象所在的代码被加载时,该对象就已经创建,并一直存在,直到进程终结。
第一次写博客,有什么不对的地方,请指出。转载请注明引用地址。
关于WeakReference一点使用经验和理解,布布扣,bubuko.com
原文:http://www.cnblogs.com/oppo-gazige/p/3604229.html