JVM之强软弱虚引用

在Java虚拟机(JVM)中,有几种不同类型的引用,它们分别是:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)和引用队列(Reference Queue)。这些引用类型提供了对对象的不同级别的引用,用于垃圾回收和内存管理。

1. 强引用(Strong Reference)

强引用是最常见的引用类型,它在程序中通过普通的对象引用方式进行声明。当一个对象具有强引用时,垃圾回收器不会回收该对象,即使内存不足也不会被回收。

示例代码:

java 复制代码
Object obj = new Object(); // 创建一个强引用对象

我们平常一般使用的引用就是强引用。

2. 软引用(Soft Reference)

软引用是一种比强引用弱一些的引用。当内存不足时,垃圾回收器可能会回收具有软引用的对象,以释放内存。这使得软引用非常适合用于实现内存敏感的高速缓存。

代码示例:

java 复制代码
public class a {

    public static void main(String[] args) throws InterruptedException {
        List<SoftReference<byte[]>> list=new ArrayList<>();
        for(int i=0;i<5;i++){
            SoftReference<byte[]> softReference=new SoftReference<>(new byte[4*1024*1024]);
            list.add(softReference);
        }
        for (SoftReference<byte[]> softReference : list) {
            System.out.println(softReference.get());
        }
    }

}

然后在vm options设置堆内存最大内存和打印垃圾回收信息参数如下:

-Xmx20m -XX:+PrintGCDetails -verbose:gc

打印日志如下:

GC (Allocation Failure) \[PSYoungGen: 2287K-\>488K(6144K)\] 14575K-\>13060K(19968K), 0.0132177 secs\] \[Times: user=0.00 sys=0.00, real=0.01 secs

GC (Allocation Failure) --\[PSYoungGen: 4584K-\>4584K(6144K)\] 17156K-\>17212K(19968K), 0.0010759 secs\] \[Times: user=0.02 sys=0.00, real=0.00 secs

Full GC (Ergonomics) \[PSYoungGen: 4584K-\>4512K(6144K)\] \[ParOldGen: 12628K-\>12559K(13824K)\] 17212K-\>17071K(19968K), \[Metaspace: 3053K-\>3053K(1056768K)\], 0.0043431 secs\] \[Times: user=0.00 sys=0.00, real=0.01 secs

GC (Allocation Failure) --\[PSYoungGen: 4512K-\>4512K(6144K)\] 17071K-\>17145K(19968K), 0.0008326 secs\] \[Times: user=0.00 sys=0.00, real=0.00 secs

Full GC (Allocation Failure) \[PSYoungGen: 4512K-\>0K(6144K)\] \[ParOldGen: 12633K-\>672K(8704K)\] 17145K-\>672K(14848K), \[Metaspace: 3053K-\>3053K(1056768K)\], 0.0036381 secs\] \[Times: user=0.00 sys=0.00, real=0.00 secs

null
null
null
null

B@ed17bee Heap PSYoungGen total 6144K, used 4378K \[0x00000000ff980000, 0x0000000100000000, 0x0000000100000000) eden space 5632K, 77% used \[0x00000000ff980000,0x00000000ffdc6828,0x00000000fff00000) from space 512K, 0% used \[0x00000000fff00000,0x00000000fff00000,0x00000000fff80000) to space 512K, 0% used \[0x00000000fff80000,0x00000000fff80000,0x0000000100000000) ParOldGen total 8704K, used 672K \[0x00000000fec00000, 0x00000000ff480000, 0x00000000ff980000) object space 8704K, 7% used \[0x00000000fec00000,0x00000000feca8218,0x00000000ff480000) Metaspace used 3062K, capacity 4486K, committed 4864K, reserved 1056768K class space used 324K, capacity 386K, committed 512K, reserved 1048576K Disconnected from the target VM, address: '127.0.0.1:63645', transport: 'socket' 当堆内存不足时,进行垃圾回收的时候,软引用对象就可以被垃圾回收。 ### 3. 引用队列(Reference Queue) 引用队列是一个专门用于管理被垃圾回收器回收的引用对象的队列。当一个对象被回收时,与之关联的引用会被放入引用队列中,以便程序可以检测到对象的回收并执行相应的操作。 ```java public class a { public static void main(String[] args) throws InterruptedException { List> list=new ArrayList<>(); ReferenceQueue referenceQueue=new ReferenceQueue<>(); for(int i=0;i<5;i++){ SoftReference softReference=new SoftReference<>(new byte[4*1024*1024],referenceQueue); list.add(softReference); } Reference poll = referenceQueue.poll(); while (poll!=null){ list.remove(poll); poll = referenceQueue.poll(); } for (SoftReference softReference : list) { System.out.println(softReference.get()); } } } ``` 使用引用队列后,就可以删除list集合中的为null的引用。打印日志不再出现null。 ### 4. 弱引用(Weak Reference) 弱引用比软引用更弱一些。弱引用的对象在下一次垃圾回收时几乎肯定会被回收,无论内存是否足够。弱引用通常用于实现对象的临时引用,例如对象的临时计算结果缓存。 代码如下: ```java public class a { public static void main(String[] args) throws InterruptedException { List> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { WeakReference weakReference = new WeakReference<>(new byte[4 * 1024 * 1024]); list.add(weakReference); for (WeakReference reference : list) { System.out.print(reference.get()+" "); } System.out.println(); } list.forEach(i-> System.out.println(i.get())); } } ``` 打印日志如下: \[B@5caf905d \[B@5caf905d \[B@27716f4 \[B@5caf905d \[B@27716f4 \[B@8efb846 \[GC (Allocation Failure) \[PSYoungGen: 2477K-\>496K(6144K)\] 14765K-\>13219K(19968K), 0.0008677 secs\] \[Times: user=0.00 sys=0.00, real=0.00 secs

B@5caf905d \[B@27716f4 \[B@8efb846 \[B@2a84aee7 \[GC (Allocation Failure) \[PSYoungGen: 4704K-\>480K(6144K)\] 17428K-\>13227K(19968K), 0.0006313 secs\] \[Times: user=0.00 sys=0.00, real=0.00 secs

B@5caf905d \[B@27716f4 \[B@8efb846 null \[B@a09ee92 \[B@5caf905d \[B@27716f4 \[B@8efb846 null \[B@a09ee92 Heap PSYoungGen total 6144K, used 4745K \[0x00000000ff980000, 0x0000000100000000, 0x0000000100000000) eden space 5632K, 75% used \[0x00000000ff980000,0x00000000ffdaa478,0x00000000fff00000) from space 512K, 93% used \[0x00000000fff80000,0x00000000ffff8020,0x0000000100000000) to space 512K, 0% used \[0x00000000fff00000,0x00000000fff00000,0x00000000fff80000) ParOldGen total 13824K, used 12747K \[0x00000000fec00000, 0x00000000ff980000, 0x00000000ff980000) object space 13824K, 92% used \[0x00000000fec00000,0x00000000ff872fa8,0x00000000ff980000) Metaspace used 3352K, capacity 4500K, committed 4864K, reserved 1056768K class space used 366K, capacity 388K, committed 512K, reserved 1048576K Process finished with exit code 0 在运行过程中每次打印信息不一样,如果中间发生一次Full GC,那么前面的list集合中的软引用对象全为null。 ### 5. 虚引用(Phantom Reference) 虚引用是最弱的引用类型,它不会阻止对象被垃圾回收。虚引用的主要作用是允许您在对象被回收时收到通知。通常与引用队列(Reference Queue)一起使用,可以在对象被回收时执行一些清理或其他操作。

相关推荐
YuTaoShao13 小时前
Java八股文——JVM「内存模型篇」
java·开发语言·jvm
张哈大1 天前
【 java 虚拟机知识 第二篇 】
java·开发语言·jvm·笔记
YuTaoShao1 天前
Java八股文——JVM「垃圾回收篇」
java·开发语言·jvm
@泽栖1 天前
讲讲JVM的垃圾回收机制
java·jvm·面试·八股文
ManageEngine卓豪1 天前
如何有效监控JVM环境,保障应用性能
jvm·虚拟机监控·应用性能监控·java 虚拟机
重庆小透明1 天前
【从零开始学习JVM | 第六篇】运行时数据区
java·jvm·后端·学习
gadiaola2 天前
【JVM面试篇】高频八股汇总——类加载和类加载器
java·jvm·面试
魔道不误砍柴功2 天前
《JVM 启动参数怎么写最优?从 Xms 到 GCLog 的调优实践》
jvm
YuTaoShao2 天前
Java八股文——JVM「类加载篇」
java·开发语言·jvm
爱玩电脑的L2 天前
javaee初阶-多线程
java·开发语言·jvm