欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > java中的强软弱虚

java中的强软弱虚

2025/5/10 12:38:58 来源:https://blog.csdn.net/github_34790294/article/details/142310438  浏览:    关键词:java中的强软弱虚

在这里插入图片描述
在java中对象的引用有强、软、弱、虚四种,这些引用级别的区别主要体现在对象的生命周期、回收时机的不同。

文章目录

    • 准备工作
      • 1. 设置内存
      • 2. 内存检测
    • 强引用
    • 软引用
    • 弱引用
    • 虚引用

准备工作

1. 设置内存

为方便调试,将内存设置为16MB

  1. 依次点击菜单栏的Run—>Edit Configurations

    在这里插入图片描述

  2. 点击 Modify options —> Add VM option
    在这里插入图片描述

  3. 添加参数
    我这里设置的内存是16m, 对应参数为 -Xms16m -Xmx16m
    在这里插入图片描述

2. 内存检测

使用 runtime.freeMemory() 的api,用来获取到未使用内存大小

强引用

这是最常见的引用,就是平时用的"=" 赋值,当将变量指向null时则表示去除了强引用,当触发gc时变量会被回收。

public static void main(String[] args) {Runtime runtime = Runtime.getRuntime();runtime.gc();System.out.println("创建数组前剩余内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");byte[] bytes = new byte[10 * 1024 * 1024];System.out.println("创建数组后所用内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");System.gc();System.out.println("触发gc后所用内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");// 去除引用关系bytes = null;System.gc();System.out.println("去除引用关系后所用内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");
}

打印结果:

创建数组前剩余内存:14.630088806152344MB
创建数组后所用内存:3.5891189575195312MB
触发gc后所用内存:3.6717300415039062MB
去除引用关系后所用内存:14.680328369140625MB

可以看出存在强引用关系时,即便触发gc该对象也不会被垃圾回收器回收

软引用

软引用引用的变量在gc时不会被回收,只有在内存不足时才会被回收。

public static void main(String[] args) {Runtime runtime = Runtime.getRuntime();runtime.gc();System.out.println("创建数组前剩余内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");SoftReference<byte[]> softReference = new SoftReference<>(new byte[10 * 1024 * 1024]);System.out.println("添加软引用后剩余内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");System.out.println("弱引用的引用对象:" + softReference.get());System.gc();System.out.println("触发gc后所用内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");System.out.println("弱引用的引用对象:" + softReference.get());// 创建一个大于剩余内存的数组byte[] newBytes = new byte[(int) (runtime.freeMemory() + 1024)];System.out.println("弱引用的引用对象:" + softReference.get());

打印结果:

创建数组前剩余内存:14.631034851074219MB
添加软引用后剩余内存:3.5826187133789062MB
弱引用的引用对象:[B@5305068a
触发gc后所用内存:3.668914794921875MB
弱引用的引用对象:[B@5305068a
弱引用的引用对象:null

使用软引用时,触发gc对象不会被垃圾回收器回收,但当内存不足时,对象会被gc回收

弱引用

    public static void main(String[] args) {Runtime runtime = Runtime.getRuntime();runtime.gc();System.out.println("创建数组前剩余内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");WeakReference<byte[]> weakReference = new WeakReference<>(new byte[10 * 1024 * 1024]);System.out.println("添加弱引用后剩余内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");System.out.println("弱引用的引用对象:" + weakReference.get());System.gc();System.out.println("弱引用的引用对象:" + weakReference.get());
}

打印结果:

创建数组前剩余内存:14.731277465820312MB
添加弱引用后剩余内存:3.5902481079101562MB
弱引用的引用对象:[B@5305068a
弱引用的引用对象:null

弱引用在gc触发后就会回收对象

虚引用

虚引用的创建与软引用、弱引用不同,它需要传入一个引用队列

    public static void main(String[] args) {Runtime runtime = Runtime.getRuntime();runtime.gc();System.out.println("创建数组前剩余内存:" + runtime.freeMemory() / 1024.0 / 1024 + "MB");ReferenceQueue<byte[]> referenceQueue  = new ReferenceQueue<>();PhantomReference<byte[]> phantomReference = new PhantomReference<>(new byte[10 * 1024 * 1024], referenceQueue);new Thread(() -> {while (true) {PhantomReference<byte[]> poll = (PhantomReference<byte[]>) referenceQueue.poll();if (poll != null) {System.out.println("虚引用对象被回收了");break;}}}).start();System.out.println("gc前虚引用的引用对象:" + phantomReference.get());System.gc();System.out.println("gc后虚引用的引用对象:" + phantomReference.get());}

输出:

创建数组前剩余内存:14.730300903320312MB
gc前虚引用的引用对象:null
虚引用对象被回收了
gc后虚引用的引用对象:null

不能通过虚引用去使用对象,主要用于跟踪对象被垃圾回收器回收的状态。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词