java的弱,虚,软引用介绍

1.弱,虚,软引用的介绍

对于绝大部分的对象而言,在程序中是存在着一个引用变量引用该对象,这是常见的引用方式,也就是常说的 强引用,对于强引用引用的对象,系统JVM是不会随意的回收资源,但是区别于强引用,对于内存敏感的程序,我们

这个内存敏感我也不清楚是啥,书上是这样说的,个人理解可能就是对于内存开支需求比较大的

也常常可以使用java.lang.ref下提供的三个包:

  • SoftReference
  • PhantomReference
  • WeakReference

这三个类分别代表了三种引用,分别是软引用,虚引用和弱引用。

2.对于四种引用的区别

  • 强引用:代表对象处于可达状态,不能被系统垃圾回收机制所回收
  • 软引用:当一个对象只有软引用的时候,可能被垃圾回收机制所回收,当内存空间足够,就不会回收,内存空间不够就另当别论
  • 弱引用:只要进行垃圾回收,就会对于这个对象进行回收,变为可恢复状态
  • 对于对象本身没有太大的影响,甚至对象是感受不到虚引用的存在的,虚引用主要用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,必须结合队列(ReferenceQueue)联合使用

对象在内存中的三种状态,分别是可达状态,可恢复状态,死亡状态

除了强引用外,其他三种引用类都有一个get()方法获取引用的对象

3.对于引用队列(ReferenceQueue)的介绍

对于软引用和弱引用,在回收完毕之后,把引用的对象和相关的引用添加到关联的引用队列之中

对于虚引用,在回收之前,把对象对应的虚引用添加到相关的队列之中,这使得可以在对象被回收之前采取行动

软引用和弱引用可以单独使用,但是虚引用一般是用来追踪对象与垃圾回收的状态,程序可以通过检查与虚引用相关的引用队列中是否包含了这个虚引用来了解这个对象是不是快要回收了

弱引用的例子

public static void main(String[]__) throws Exception
{
//创建一个字符串对象,注意要使用new方法,而不是直接string a=“xxx”,这样字符串会在常量池导致无法回收
String str=new String("山威");
//创建一个弱引用,让弱引用引用这个str
ReferenceQueue<String> que=new ReferenceQueue<>();
WeakReference<String> wr=new WeakReference<String>(str,que);
//切断str与字符串的联系
str=null; //在这里取出弱引用对象
System.out.println(wr.get()); //在这里进行内存回收
System.gc();
System.runFinalization(); System.out.println(wr.get()); //再次从队列取出来看看
System.out.println(que.poll().get());
}



这里是代码输出的结果,可以看到在强制垃圾回收之后,弱引用丢失了对象,而队列那个嘛,是我加进去试试的,其实引用队列我也不太会,hhh

内存中的样子

虚引用的列子

public static void main(String[]__) throws Exception
{
//创建一个字符串对象,注意要使用new方法,而不是直接string a=“xxx”,这样字符串会在常量池导致无法回收
String str=new String("山威");
//创建一个弱引用,让弱引用引用这个str
ReferenceQueue<String> que=new ReferenceQueue<>();
PhantomReference<String> ph=new PhantomReference<String>(str,que);
//切断str与字符串的联系
str=null; //在这里取出弱引用对象
//不会输出东西,因为不能使用虚引用访问对象
System.out.println(ph.get()); //在这里进行内存回收
System.gc();
System.runFinalization(); //回收之后,虚引用进入队列
//再次从队列取出来看看
System.out.println(que.poll()==ph);
}

输出结果



进入队列之后判断,所以这里最后一个输出是true

4.作用分析

使用这些引用类可以避免在程序执行期间将对象留在内存中。如果以软引用、弱引用或虚引用的方式引用对象,垃圾收集器就能够随意地释放对象。如果希望尽可能减小程序在其生命周期中所占用的内存大小时,这些引用类就很有用处。

必须指出:要使用这些特殊的引用类,就不能保留对对象的强引用;如果保留了对对象的强引用,就会浪费这些引用类所提供的任何好处。 《java疯狂讲义》


//取出弱引用所引用的对象
obj=wr.get();
//如果取出的对象为null
if (obj==null)
{
//重新创建一个新的对象,并使用强引用来引用它
obj=recreateIt();
//取出弱引用所引用的对象,将其赋给obj变量
wr=new WeakReference(obj);
}
...//操作obj对象
//再次切断obj和对象之间的关联
obj=null;

例子也是使用 《java疯狂讲义》的,这书除了讲的太细了,其他都好

首发于博客园(博客园不能一边写一遍浏览,所以是写到csdn搬过来,但是没在csdn发布的)--2021.10.28

java中的软,弱,虚引用介绍与特性分析的更多相关文章

  1. java中强,软,弱,虚引用 以及WeakHahMap

    java中强,软,弱,虚引用  以及WeakHahMap   一:强软引用: 参考:http://zhangjunhd.blog.51cto.com/113473/53092/进行分析   packa ...

  2. java中的强,软,弱,虚引用

    引用的应用场景 我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型.这正是Java中弱引用和软引用的主要区别. 如果一个对象只有弱引用指向 ...

  3. 转载:Java中的字符串常量池详细介绍

    引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...

  4. 一道笔试题来理顺Java中的值传递和引用传递

      题目如下: private static void change(StringBuffer str11, StringBuffer str12) { str12 = str11; str11 = ...

  5. java中的值传递和引用传递有什么区别呀?

    值传递: (形式参数类型是基本数据类型和String):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参 ...

  6. Java 中的值传递和引用传递问题

    Java 中的值传递和引用传递问题 public class Operation { int data = 50; void change(int data) { data = data + 100; ...

  7. java中的compareto方法的详细介绍

    java中的compareto方法的详细介绍 Java Comparator接口实例讲解(抽象方法.常用静态/默认方法) 一.java中的compareto方法 1.返回参与比较的前后两个字符串的as ...

  8. (转)Java中的值传递和引用传递

    Java中的值传递和引用传递 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?     答:是值传递.Java 编程语言只有值 ...

  9. java中的软引用,弱引用,虚引用

    http://zh.wikipedia.org/wiki/%E5%BC%B1%E5%BC%95%E7%94%A8 有些语言包含多种强度的弱引用.例如Java,在java.lang.ref[1]包中定义 ...

随机推荐

  1. CentOS 7操作系统安装

    1.关于运维小伙伴可以采用何种方式安装操作系统 下面列举的只是我会用到的安装方式,在运维过程中并不一定是最优解,只是自己运维过程中的一些经验. (1)物理服务器,可以通过连接管理口来安装操作系统,管理 ...

  2. Tars | 第7篇 TarsJava Subset最终代码的测试方案设计

    目录 前言 1. SubsetConf配置项的结构 1.1 SubsetConf 1.2 RatioConfig 1.3 KeyConfig 1.4 KeyRoute 1.5 SubsetConf的结 ...

  3. systemctl添加自定义系统服务

    [Service] Type=forking ExecStart=绝对路径 ExecStop=绝对路径 ExecReload=绝对路径 以上最精简版,文件/usr/lib/systemd/system ...

  4. scrum项目冲刺_day10总结

    摘要:今日完成任务. 1.发布功能实现 2.导航还在进行 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已完成) 2.语音识别功能(已完成) 3.垃圾搜索功能(基本完成) ...

  5. Django学习day10随堂笔记

    每日测验 """ 今日考题 1.默写ajax基本语法,及提交json数据和文件都需要添加哪些额外参数 2.什么是序列化,截止目前为止你所接触过的序列化有哪些 3.批量插入 ...

  6. 5ucms的评论列表该怎么写

    查看所有评论 <a href="{sys:plusurl}comment/?id={field:id}">查看所有评论</a> <linkhref=& ...

  7. python刷题第三周

    以下是本周有所收获的题目 第一题: 第4章-4 验证"哥德巴赫猜想" (20 分) 数学领域著名的"哥德巴赫猜想"的大致意思是:任何一个大于2的偶数总能表示为两 ...

  8. 在Ubuntu18.04安装docker之后,以登陆用户身份执行docker pull jenkins,报错:connect: permission denied

    Using default tag: latest Got permission denied while trying to connect to the Docker daemon socket ...

  9. AT3945-[ARC092D]Two Faced Edges【dfs】

    正题 题目链接:https://www.luogu.com.cn/problem/AT3945 题目大意 \(n\)个点\(m\)条边的一张图,对于每条边求它翻转后强连通分量数量是否变化. \(1\l ...

  10. P3980-[NOI2008]志愿者招募【费用流】

    正题 题目链接:https://www.luogu.com.cn/problem/P3980 题目大意 \(n\)天,第\(i\)天需要\(A_i\)个志愿者.有\(m\)种志愿者,第\(i\)种从\ ...