Java中的引用
前言
整体架构
强引用
软引用
弱引用
软引用和弱引用的使用场景
WeakHashMap是什么?
虚引用
概念
场景
引用队列 ReferenceQueue
GCRoots和四大引用小总结
前言
在原来的时候,我们谈到一个类的实例化
Person p = new Person()
1
在等号的左边,就是一个对象的引用,存储在栈中
而等号右边,就是实例化的对象,存储在堆中
其实这样的一个引用关系,就被称为强引用
整体架构
强引用
当内存不足的时候,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,打死也不回收~!
强引用是我们最常见的普通对象引用,只要还有一个强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到,JVM也不会回收,因此强引用是造成Java内存泄漏的主要原因之一。
对于一个普通的对象,如果没有其它的引用关系,只要超过了引用的作用于或者显示地将相应(强)引用赋值为null,一般可以认为就是可以被垃圾收集的了(当然具体回收时机还是要看垃圾回收策略)
强引用小例子:
/** * 强引用 * @author: 轻狂书生FS * @create: 2020-04-23-16:25 */ public class StrongReferenceDemo { public static void main(String[] args) { // 这样定义的默认就是强应用 Object obj1 = new Object(); // 使用第二个引用,指向刚刚创建的Object对象 Object obj2 = obj1; // 置空 obj1 = null; // 垃圾回收 System.gc(); System.out.println(obj1); System.out.println(obj2); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
输出结果我们能够发现,即使 obj1 被设置成了null,然后调用gc进行回收,但是也没有回收实例出来的对象,obj2还是能够指向该地址,也就是说垃圾回收器,并没有将该对象进行垃圾回收
null java.lang.Object@14ae5a5
1
2
软引用
软引用是一种相对弱化了一些的引用,需要用Java.lang.ref.SoftReference类来实现,可以让对象豁免一些垃圾收集,对于只有软引用的对象来讲:
当系统内存充足时,它不会被回收
当系统内存不足时,它会被回收
软引用通常在对内存敏感的程序中,比如高速缓存就用到了软引用,内存够用 的时候就保留,不够用就回收
具体使用
/** * 软引用 * * @author: 轻狂书生FS * @create: 2020-04-23-16:39 */ public class SoftReferenceDemo { /** * 内存够用的时候 */ public static void softRefMemoryEnough() { // 创建一个强应用 Object o1 = new Object(); // 创建一个软引用 SoftReference