5.4 软引用
上文说到,如果一个对象在它的引用链上没有GC Root对象,那么这个对象就可以被回收,如果有GC Root对象,那么这个对象就不能被回收。其实对象还有其他回收的机制。
Java中主要有五种引用方式。
可达性分析算法中描述的引用,一般都是强引用,即是GC Root对象对普通对象有引用关系,只要这层关系存在,那么普通对象就不会被回收。除了强引用以外,Java中还有其中几种引用方式:
- 软引用
- 弱引用
- 虚引用
- 终结器引用
强引用的对象,必定不会被回收。软引用就不同,在一般情况下(堆内存充足时)不会回收这个对象,当堆内存不够用的时候,软引用对象会被强制回收。
对象本身没有软引用,如果想让一个对象软引用,需要new出一个软引用SoftReference
保存想要软引用的对象。值得注意的是SoftReference
对象也要通过引用链关联到GC Root对象,否则这个对象就会被立即回收了(通常创建一个列表将软引用保存起来,让其可达即可)。
软引用一般都是应用在缓存上,因为缓存上的数据只是为了提高速度,并不会因为强制回收而导致系统崩溃。
SoftReference
对象本身也需要被回收,如何知道这个对象需要被回收呢?
软引用还有另一种使用方法:
5.5 软引用的应用场景——缓存
创建一个缓存类,里边存放着一个哈希表,哈希表的键是学生的哈希值,哈希表的值是软引用。当内存不够用,哈希表中软引用存放的学生数据会被回收,此时只需要获得软引用队列,弹出已经被回收数据的软引用,从哈希表中移除键值对,之后软引用也会被回收。
5.6 弱引用、虚引用和终结器引用
弱引用的整体机制跟软引用一致,但是存放在弱引用中的数据无论内存够不够用,都会被回收(这样有无弱引用貌似没区别?)。
主要使用WeakReference
类来实现弱引用,弱引用主要在ThreadLocal
中使用。弱引用对象也可以使用引用队列进行回收。
之后是虚引用和终结器引用: