几种引用的区别
Java中的引用类似C++中的指针,用来指向一个对象,指向对象的变量叫做引用变量,除了8中基本类型,其他的类型都是引用类型,主要包括:类、接口、数组、枚举、注解。
主要分为四种引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference),引用强度依次减弱,生命周期也不一样。JVM的垃圾回收机制分别进行不同的处理。
强引用
最常见的一种引用,是将一个对象赋值给另一个引用变量,这个引用变量就是强引用,当一个对象被强引用变量引用时,一直是可到达状态,GC是不能回收的,因此也是导致内存泄漏的常见原因之一,比如:
1 | Object obj1 = new Object(); |
软引用
如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存 空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联 的引用队列中。
使用SoftReference
类实现。
栗子代码:
1 | /** |
弱引用
弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
使用WeakReference
类实现,比软引用的生命周期更短,只要GC发生就会回收。
如Java中的WeakHashMap
类,当key置空后,下一次垃圾回收后,对应的键值对就会被回收。
1 | private static void weakMap(){ |
虚引用
虚引用,顾名思义,就是形同虚设,与其他几种引用都不太一样,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问对象,虚引用必须和引用队列(RefenenceQueue)联合使用。
虚引用的主要作用是跟踪对象垃圾回收的状态。仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。PhantomReference 的 get 方法总是返回 null,因此无法访问对应的引用对象。其意义在于说明一个对象已经进入 finalization 阶段,可以被 GC 回收,用来实现比 finalization 机制更灵活的回收操作。