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. SQLmap的基本命令

    Sqlmap sqlmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL进行SQL注入.目前支持的数据库有MySql.Oracle.Access.PostageSQL.SQL  ...

  2. 简单学习PHP中的层次性能分析器

    在 PHP 中,我们需要进行调试的时候,一般都会使用 memory_get_usage() 看下内存的使用情况.但如果想看当前的脚本 CPU 的占用情况就没有什么现成的函数了.不过,PHP 也为我们提 ...

  3. symfony2已有数据表导入实体时报错 Doctrine does not support reverse engineering from tables that don't have a primary key

    先在配置文件 app/config/config.yml中配置 schema_filter: /^(?!(tablename))/ 即可,或者在出现问题表都加上一个id 然后再使用命令 php app ...

  4. Docker系列(27)- 容器互联--link

    思考 思考一个场景,我们编写了一个微服务,database url=IP:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以使用名字来进行访问容器吗 实践 [root@localhost ...

  5. HCNP Routing&Switching之路由控制-策略路由

    前文我们了解了路由策略工具Route-Policy相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15322135.html:今天我们来聊一聊策略路由相 ...

  6. django安装xadmin

    环境:pycharm  django1.11.20  python2.7(根据网络上的资料,自己整理实现) 下载:https://github.com/sshwsfc/xadmin/tree/mast ...

  7. 鸿蒙内核源码分析(汇编传参篇) | 如何传递复杂的参数 | 百篇博客分析OpenHarmony源码 | v23.02

    百篇博客系列篇.本篇为: v23.xx 鸿蒙内核源码分析(汇编传参篇) | 如何传递复杂的参数 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪 ...

  8. position的五个不同的位置值

    一.position: static  无定位 HTML 元素默认情况下的定位方式为 static(静态). 静态定位的元素不受 top.bottom.left 和 right 属性的影响. posi ...

  9. Digital Image Processing

    20190919 Review CCD:高端天文学,敏感度高,速度慢,成本高: CMOS:普遍使用,嵌入手机,速度快,有模式噪声(Pattern Noise,现在可以解决): 空间分辨率和时间分辨率: ...

  10. Windows10通过WSL编译jdk12

    Windows使用WSL编译OpenJDK 安装Ubuntu以及配置国内镜像 首选确保windows10已经安装了ubuntu 更换ubuntu20.04国内镜像,这里我选择的是阿里云镜像 sudo ...