Java具有四种不同强度的引用类型:
强引用:
被强引用关联的对象不会被回收,一般通过new来构造对象时,就会返回一个强引用。
Object obj = new Object()
软引用:
通过SoftReference来构造,会在内存不足时回收,一般可用于缓存等场景,比如MyBatis中缓存的装饰器就有SoftCache类型。在Class.java中用于保存反射数据
弱引用:
通过WeakReference来构造,会在下次GC时回收,也可用于缓存场景,MyBatis缓存装饰器WeakCache。
线程类中,ThreadLocalMap
中的Entry
的key
就使用弱引用,在这里key是ThreadLocal类型。会在发生GC时回收,所以这里还会涉及key被回收导致的内存泄漏问题,使用ThreadLocal后记得调用remove释放value。
虚引用(幽灵引用):
通过PhantomReference来构造,不对对象的生存时间产生影响,也无法通过虚引用来获得对象。为一个对象设置虚引用关联的唯一目的就是能在这个对象被回收时收到一个系统通知。
sun.misc中的Cleaner类就继承自虚引用。该类用于直接操作内存相关的类,即DirectXXXBuffer系列,在构造DirectXXXBuffer时,会构造一个虚引用的Cleaner指向自己,并传入一个Runnable对象,当对象被回收时,会触发Cleaner的clean
方法,并进一步执行Runnable对象的run
方法,通过unsafe回收直接内存。
Reference类有个静态代码块,会创建一个最高优先级的引用处理线程,会一直循环调用tryHandlePending
方法, 处理挂起的引用,如果发现存在Cleaner对象,就执行Clean.clean,并执行引用入队操作。J