概念
- 每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过“引用”。
- 在对Java引用数据类型对象进行操作时,使用的标识符实际上是内存对象的一个引用(reference)。
- Java 中的垃圾回收机制在判断是否回收某个对象的时候,都需要依据“引用”这个概念。
- 一个对象只有“已被引用”和 "未被引用"两种状态,为方便内存回收,所以在JDK1.2后,将引用分为了四种类型;
-
强引用、软引用、弱引用、虚引用。引用强度依次减弱。
强引用 Strong Reference
- Java中默认声明的就是强引用,=号赋值。
- 垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。
- 显示的将强引用赋值为null,可以切断强引用与对象之间的联系,垃圾回收器将回收内存
Object obj = new Object(); //只要obj还指向Object对象,Object对象就不会被回收
obj = null; //手动置null
软引用 Soft Reference
- 在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。
- 这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。
SoftReference<类型名称> sr = new SoftReference<>(对象名称);
byte[] buff = new byte[1024 * 1024];
SoftReference<byte[]> sr = new SoftReference<>(buff);
弱引用 Weak Reference
- 弱引用的引用强度比软引用要更弱一些
- 无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。
WeakReference<类型名称> sr = new WeakReference<>(对象名称);
byte[] buff = new byte[1024 * 1024];
WeakReference<byte[]> sr = new WeakReference<>(buff);
虚引用 Phantom Reference
- 虚引用是最弱的一种引用关系
- 如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收
- 它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象
- 虚引用必须要和 ReferenceQueue 引用队列一起使用。
引用队列 ReferenceQueue
- 当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。