引用的架构图:
Reference在java.lang.ref包下
1、强引用(默认)
将对象赋值给以引用变量,这个引用变量就是一个强引用,这个强引用指向的对象即使出现了OOM也不会被回收。
代码举例:
obj2也是强引用,所以即使obj不再指向new Object()对象了,但是该对象依旧不会被GC
2、软引用
SoftReference softReference = new SoftReference<>(new Object());
适用于对内存敏感的程序中,如高速缓存:
即软引用只会因内存不够用引起的gc时被回收(前提是强引用不存在),而不是一旦gc就会被回收。
代码举例:
内存够用的时候:(软引用不会被回收)
注意,该软引用的对象仍然不会被GC,因为没有OOM!即使其内封装的o1引进置为空了,也不会影响
结果:
内存不够用的时候:(软引用会被回收)
不需要手动System.gc(),因为内存不够用了,会自动gc;
需要在IDEA中配置JVM参数,见方法的注释。
结果:
(最后一行显示,该软引用被gc了)
另外OOM也会报错,只是这里没有截出来
小总结:软引用会被垃圾回收的场景:强引用置为空了,且因为OOM而引起GC时,即
OOM,引起的gc不会使软引用被回收;
强引用置为空了,调用System.gc();不会引起软引用的回收;
3、弱引用(比软引用的生存期更短)
WeakReference weakReference = new WeakReference<>(new Object());
但也只有被认定为垃圾后,才会回收(所以需要o1 = null这行代码)
代码举例:
结果:(即使在内存充足的情况下,只要发生GC,弱引用就会被回收)
软引用、弱引用的适用场景:
键:String:图片路径
值:SoftReference<Bitmap>:相应图片对象关联的软(弱)引用
使用imageCache作为缓存,每加载了一张图片,就存进这个imageCache里(本质是HashMap.put())
详细代码:(Image换成正确的)
小总结:弱引用会被垃圾回收的场景:强引用置为空了,一旦GC(即不要求是OOM引起的gc),即
gc不会使软引用被回收;(还必须要强引用置为空)
既然你知道弱引用,那么你还知道WeakHashMap吗?
HashMap和WeakHashMap一样地位,都是继承AbstractMap抽象类,实现Map接口
直接上代码,比较HashMap和WeakHashMap的区别
结果:(WeakHashMap是一种弱引用map,内部的key会自动存储为弱引用,当jvm gc的时候,如果这些key没有强引用存在的话,会被gc回收掉,下一次当我们操作map的时候会把对应的Entry整个删除掉,基于这种特性,WeakHashMap特别适用于缓存处理。)
即缓存处理,可以
1、将软引用(发生了OOM才会被清除)作为普通hashMap的值放入;(若想删除某个图片,只需将image置为null,当下次发生OOM时,该普通hashMap中的该键值图片会被自动删除)
2、也可以将普通(未被封装成软引用)的图片对象作为WeakHashMap的值放入。(若想删除某个图片,只需将该image对应的键(即key)设为null,当下次gc时,会被删掉)
会被回收情况的小总结:
1、软引用
强引用为空 +
OOM引发的gc .
2、弱引用
强引用为空 +
gc(不要求是OOM引发的) .
4、虚引用
![](https://img-blog.csdnimg.cn/20200618154528527.png)
引用的构造方法可以(至少软引用、弱引用、虚引用可以, 强引用怎么搞没验证)填上第二个参数:引用队列。
![](https://img-blog.csdnimg.cn/20200618154603349.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzY5NTkxMQ==,size_16,color_FFFFFF,t_70)
(此处之所以用WeakReference而不用PhantomReference的原因是因为PhantomReference的不能通过它访问对象的特点,而不方便作为代码展示,所以用的是WeakReference(事实上,软、弱引用都可以)来和ReferenceQueue结合)
(事实上,软、弱引用都可以和ReferenceQueue结合,这些引用达到GC条件时,都会把对象先放进ReferenceQueue中,再清除自己本身,见结果最后一行(非null))
注意一下WeakReference的构造方法,两个参数!多了一个ReferenceQueue
![](https://img-blog.csdnimg.cn/20200618154618607.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzY5NTkxMQ==,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20200618154628382.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzY5NTkxMQ==,size_16,color_FFFFFF,t_70)
虚引用和引用队列的结合,完完全全是为了实现通知机制。
![](https://img-blog.csdnimg.cn/20200618154646886.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzY5NTkxMQ==,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20200618154654614.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzY5NTkxMQ==,size_16,color_FFFFFF,t_70)