【WeakReference】WeakReference 弱引用的认识
1 前言
这节我们聊聊 WeakReference 弱引用的作用,因为我们平时看源码的时候会发现一些对象是继承了这个类的,那么这个类是干什么的?
我的理解哈这个类是专门给 GC 标识用的,当一个类 A 继承了 WeakReference 就表示 A 如果没有别的强引用的话,我 GC 的时候是可以回收掉 A对象的,下边我们会有示例讲解。
2 简介
WeakReference 简称弱引用/软引用
特定:弱引用的对象会在GC时被回收,无论系统内存是否足够。
常用场景:大量对象的创建可能会出现OOM异常,利用弱引用或软引用可以在堆内存不足时回收部分对象,释放空间。
我们简单来看下 WeakReference 的类图,关系比较简单就是继承了引用类。
可以看看 WeakReference 的构造方法就是传入我们的真实对象:
/** * Reference 类 * @param referent 我们的真实对象 */ Reference(T referent) { this(referent, null); } /** * WeakReference类 * @param referent 我们的真实对象 */ public WeakReference(T referent) { super(referent); }
再来看一个 get 方法,就是返回我们的真实对象:
// Reference 类 public T get() { return this.referent; }
3 测试与感知
简单介绍了 WeakReference 我们就来测测它的具体效果,代码示例如下:
public class TestWeakReference { // Person类 static class Person { private String name; Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } // Person的弱引用类 static class PersonWeakReference extends WeakReference<Person> { public PersonWeakReference(Person referent) { super(referent); } } public static void main(String[] args) { // 创建弱引用 PersonWeakReference personWeakReference = new PersonWeakReference(new Person("狗子")); System.out.println("回收前:" + personWeakReference.get()); // GC 进行回收,并不会立刻执行,只是建议 jvm 进行 gc System.gc(); System.out.println("回收后:" + personWeakReference.get()); } }
IDEA 配置上GC日志,可以看是否有 GC 发生。
3.1 单纯的弱引用
public static void main(String[] args) { // 创建弱引用 PersonWeakReference personWeakReference = new PersonWeakReference(new Person("狗子")); System.out.println("回收前:" + personWeakReference.get()); // GC 进行回收,并不会立刻执行,只是建议 jvm 进行 gc System.gc(); System.out.println("回收后:" + personWeakReference.get()); }
3.2 存在强引用
public static void main(String[] args) { // 这里有个强引用 Person person = new Person("狗子"); // 创建弱引用 PersonWeakReference personWeakReference = new PersonWeakReference(person); System.out.println("回收前:" + personWeakReference.get()); // GC 进行回收,并不会立刻执行,只是建议 jvm 进行 gc System.gc(); System.out.println("回收后:" + personWeakReference.get()); }
3.3 OOM的角度感知
配置 -Xmx50m 设置堆的大小,然后我们写一个内存溢出的例子:
public static void main(String[] args) { List<byte[]> list = new ArrayList<>(); for (int i = 0; i < 50; i++) { // 1024B = 1K 再乘 1024 = 1M byte[] item = new byte[1024 * 1024]; list.add(item); } }
那我们用弱引用再来感知下:
static class ByteWeakReference extends WeakReference<byte[]> { public ByteWeakReference(byte[] referent) { super(referent); } } public static void main(String[] args) { List<ByteWeakReference> list = new ArrayList<>(); for (int i = 0; i < 50; i++) { // 1024B = 1K 再乘 1024 = 1M ByteWeakReference byteWeakReference = new ByteWeakReference(new byte[1024 * 1024]); list.add(byteWeakReference); } }
4 小结
这节我们主要认识了一下 WeakReference 弱引用,它主要是用来影响一个 GC的效果,也从几个测试点大概感受了下,有理解不对的地方欢迎指正哈。
分类:
源码 / JDK
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性