概述
jdk1.2+就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。这四种引用被回收的容易程度由低到高依次为:强引用、软引用、弱引用和虚引用。
Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决定某些对象的生命周期;第二是有利于JVM进行垃圾回收。
各种引用的java实现
软引用:通过java.lang.ref.SoftReference类来包装对象
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
弱引用:java.lang.ref.WeakReference类来包装对象
WeakReference<String> sr = new WeakReference<String>(new String("hello"));
虚引用:通过java.lang.ref.PhantomReference类来包装对象
ReferenceQueue<String> queue = new ReferenceQueue<String>();//虚引用必须和引用队列关联使用
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
强引用:不使用以上引用方式创建的对象都属于强引用
使用场景
-
强引用:除非对象没有了引用,否则不会被gc回收。如将对象的引用赋值为null,这样JVM在合适的时间就会回收该对象。
-
软引用:当内存空间不足了,就会回收这些对象的内存。软引用可用来实现内存敏感的高速缓存。
-
弱引用:当gc进行扫描内存时,一旦发现有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。Weak引用对象常常用于Map数据结构中,以及适合缓存占用内存空间较大但可以随时释放的对象。
-
虚引用:当gc进行扫描内存时,如果发现有虚引用的对象,先把这个对象放到与之关联的引用队列中,直到引用队列被处理才回收队列里的对象。虚引用主要用来跟踪对象被垃圾回收器回收的活动
WeakHashMap
WeakHashMap的存储结构类似于HashMap,内部是通过弱键key来管理 Entry 的,当调用WeakHashMap的方法的时候就会把 不用的Entry(就是key没有被强引用) 释放掉并把Entry.value赋值为null,以便被GC回收。WeakHashMap适合短时间内就过期的缓存场景。
注意点
-
通过System.gc()/Runtime.getRuntime().gc() 来通知JVM进行垃圾回收,但是要注意的是,虽然发出了通知,JVM不一定会立刻执行垃圾回收。
-
软引用、弱引用允许和一个引用队列联合使用,如果所引用的对象被垃圾回收,Java虚拟机就会把这个对象加入到与之关联的引用队列中,以便对这些被清除的弱引用对象进行统一管理。