当前位置: 首页 > article >正文

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

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


http://www.kler.cn/news/328732.html

相关文章:

  • SQL Server—表格详解
  • C++ 游戏开发:奠定高性能游戏的基础
  • 【MySQL】-- 数据库基础
  • 微信小程序map组件自定义气泡真机不显示
  • 通信工程学习:什么是MAC媒体接入控制
  • 在C#中使用JSON
  • 链表的实现(go语言)
  • 【AIGC】ChatGPT提示词解析:如何打造个人IP、CSDN爆款技术文案与高效教案设计
  • DVWA | File Inclusion(文件包含)渗透测试
  • 十三、减少磁盘延迟时间的方法
  • SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS
  • Linux 文件 IO 管理(第三讲:文件系统)
  • vue从入门到精通
  • 成都睿明智科技有限公司抖音电商服务靠谱吗?
  • 前端如何实现图片伪防盗链,保护页面图片
  • 甄选范文“论网络安全体系设计”,软考高级论文,系统架构设计师论文
  • web开发(1)-基础
  • 什么是信息增益
  • MacOS配置python环境
  • 编程参考 - 动态链接库中的变量实例化
  • AccessoriesqueryController
  • 【韩顺平Java笔记】第5章:程序控制结构
  • 【异常数据检测】孤立森林算法异常数据检测算法(数据可视化 Matlab语言)
  • GPT对话代码库——esp32和单片机实现远程wifi升级代码方案。
  • windows系统中后台运行java程序
  • OIDC6-OIDC 授权流程类型
  • 秘密武器揭秘
  • 全国职业院校技能大赛(大数据赛项)-平台搭建Zookeeper笔记
  • 创新型城市试点名单最新数据(2006-2023年)
  • 【Nacos架构 原理】内核设计之Nacos通信通道