软引用和弱引用的区别_强引用软引用弱引用虚引用的区别

软引用和弱引用的区别_强引用软引用弱引用虚引用的区别示例代码:importjava.lang.ref.SoftReference;/***@authorchenjc*@since2020-01-13*/publicclassSoftReferenceTest{/***使用JVM参数-Xmx10m运行程序**@paramargs*@throwsI…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

示例代码:

import java.lang.ref.SoftReference;
/** * @author chenjc * @since 2020-01-13 */
public class SoftReferenceTest { 

/** * 使用JVM参数-Xmx10m运行程序 * * @param args * @throws InterruptedException */
public static void main(String[] args) throws InterruptedException { 

User user = new User(1, "debo");
// 建立User对象的软引用
SoftReference<User> userSoftReference = new SoftReference<>(user);
// 去掉强引用
user = null;
System.out.println(userSoftReference.get());
// 手动触发GC
System.gc();
System.out.println("第一次GC: " + userSoftReference.get());
// 分配适量内存空间,造成内存资源紧张,产生GC,同时又不会导致堆内存溢出
byte[] bytes = new byte[6 * 1024 * 1050];
System.out.println("第二次GC: " + userSoftReference.get());
}
private static class User { 

private Integer id;
private String name;
public User(Integer id, String name) { 

this.id = id;
this.name = name;
}
public Integer getId() { 

return id;
}
public void setId(Integer id) { 

this.id = id;
}
public String getName() { 

return name;
}
public void setName(String name) { 

this.name = name;
}
@Override
public String toString() { 

return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
}

使用JVM参数-Xmx10m运行此程序,输出如下:

User{id=1, name='debo'}
第一次GC: User{id=1, name='debo'}
第二次GC: null

第一次GC的时候,软引用没有被回收,是因为这时候内存资源充足。第二次由于分配了较大的内存,导致GC,这时候由于内存资源紧张,软引用被回收了,也就是虽然User对象有一个软引用在引用着它,但User对象在此条件下也会被GC回收。所以软引用的对象在一定条件下可被回收,故软引用对象不会导致内存溢出。

软引用到底有没有被回收,可以通过给软引用一个ReferenceQueue来跟踪,将上面的代码片段稍作修改,如下:

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
/** * @author chenjc * @since 2020-01-13 */
public class SoftReferenceTest { 

/** * 使用JVM参数-Xmx10m运行程序 * * @param args * @throws InterruptedException */
public static void main(String[] args) throws InterruptedException { 

User user = new User(1, "debo");
// 建立User对象的软引用
ReferenceQueue<User> userReferenceQueue = new ReferenceQueue<>();
UserSoftReference userSoftReference = new UserSoftReference(user, userReferenceQueue);
// 去掉强引用
user = null;
System.out.println(userSoftReference.get());
// 手动触发GC
System.gc();
System.out.println("第一次GC: " + userSoftReference.get());
System.out.println("第一次GC队列: " + userReferenceQueue.remove(1000));
// 分配适量内存空间,造成内存资源紧张,产生GC,同时又不会导致堆内存溢出
byte[] bytes = new byte[6 * 1024 * 1055];
System.out.println("第二次GC: " + userSoftReference.get());
Reference<? extends User> reference = userReferenceQueue.remove(1000);
if (reference != null) { 

UserSoftReference userSoftReference1 = (UserSoftReference) reference;
System.out.println("第二次GC队列: " + userSoftReference1.getId());
}
}
private static class User { 

private Integer id;
private String name;
public User(Integer id, String name) { 

this.id = id;
this.name = name;
}
public Integer getId() { 

return id;
}
public void setId(Integer id) { 

this.id = id;
}
public String getName() { 

return name;
}
public void setName(String name) { 

this.name = name;
}
@Override
public String toString() { 

return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
private static class UserSoftReference extends SoftReference<User> { 

private Integer id;
public UserSoftReference(User referent, ReferenceQueue<? super User> q) { 

super(referent, q);
this.id = referent.id;
}
public Integer getId() { 

return id;
}
public void setId(Integer id) { 

this.id = id;
}
}
}

输出如下:

User{id=1, name='debo'}
第一次GC: User{id=1, name='debo'}
第一次GC队列: null
第二次GC: null
第二次GC队列: 1

第一次GC没有回收软引用对象,所以ReferenceQueue为空,第二次GC回收了软引用对象,所以ReferenceQueue队列不为空,那为什么可以强转成UserSoftReference呢?是因为队列里面的reference就是方法局部变量userSoftReference。此处自定义一个UserSoftReference类主要是为了跟踪User对象的id,你无法跟踪User对象,因为User对象已经被回收了,如果调用reference.get(),将会返回null。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/195980.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 手把手教你打造一个企业级实时数据中台【万字图文】「建议收藏」

    手把手教你打造一个企业级实时数据中台【万字图文】「建议收藏」引言——首先来聊聊现代企业数据架构及痛点:数据孤岛:低效率和利用困难的根源应用瓶颈:传统方案数据仓库、数据湖的不足 单讲这两个问题你可能会疑惑——为什么会出现这样的问题? 所以下面来讲讲两个实际的例子来细讲一下这两个问题:第一部分——两个实际的场景例子引入1.以航空公司的场景为例:  航空公司的市场部计划推出一个新产品或者是一个客户活动,会希望了解哪一种渠道是某类客户最常用的?当想到这个问题的时候,发现航空公司的客户触点太多了。  PSDP行程订单,投诉、行李系统,常旅客系统,手.

  • Java安全之Weblogic内存马

    Java安全之Weblogic内存马0x00前言发现网上大部分大部分weblogic工具都是基于RMI绑定实例回显,但这种方式有个弊端,在WeblogicJNDI树里面能将打入的RMI后门查看

    2021年12月13日
  • 银河麒麟安装qt开发环境_优麒麟怎么样

    银河麒麟安装qt开发环境_优麒麟怎么样1.如果你对中标麒麟系统安装有疑问,请阅读上一篇文章:《中标麒麟/NeoKylinU盘安装系统》。2.进入系统打开终端,以root模式操作。&lt;1&gt;yuminstallgstream*libXext-devellibX11-devel&lt;2&gt;ln-s/usr/lib64/libXrender.so.1.3.0/usr/lib64/libXrend…

  • python 报表开发工具_自定义报表 开源

    python 报表开发工具_自定义报表 开源BIRT报表是一款非常流行的开源报表开发工具。拥有和Dreamweaver一般的操作界面,可以像画table一样画报表,生成图片,导出Excel,html分页样样齐全,样式和script设置简单。PentahoReportDesigner是一款所见即所得的开源报表设计工具。在设计报表的时候,用户可以随意拖放和设置各种报表的控件,还可以快速方便地设置报表的数据来源。在报表的设计过程中,用户可…

    2022年10月20日
  • LayuiAdmin模板(0积分免费下载,非单独框架)

    LayuiAdmin模板(0积分免费下载,非单独框架)点击这里直接下载LayuiAdmin模板

    2022年10月24日
  • vim的配置_vim全局配置

    vim的配置_vim全局配置vim前端全家桶配置指南简介因为写了一段时间前端,一直在考虑vim是否能够替代前端无敌编辑器vscode,最后发现只能高仿,自己配置的性能跟vscode下的vim模式差不多,灵活性更高点,喜欢折腾的朋友可以试试,否则用vscodevim模式吧,已经神一般的完美了(不是高级黑-。-)。这套插件目前包含了代码自动补全,目录树,js/jsxeslint自动格式化,小黑屋模式,文件搜索ctr…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号