深入Java(二):Java中的强引用、软引用、弱引用、幻像引用( 虚引用)

2023-11-10

在Java语言中,除了基本数据类型外,其他的都是指向各类对象的对象引用;Java中根据其生命周期的长短,将引用分为4类。


1 强引用

特点:我们平常典型编码Object obj = new Object()中的obj就是强引用。通过关键字new创建的对象所关联的引用就是强引用。 当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足的问题。对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为 null,就是可以被垃圾收集的了,具体回收时机还是要看垃圾收集策略。

2 软引用

特点:软引用通过SoftReference类实现。 软引用的生命周期比强引用短一些。只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象:即JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。后续,我们可以调用ReferenceQueue的poll()方法来检查是否有它所关心的对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。


应用场景:软引用通常用来实现内存敏感的缓存。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。

3 弱引用

弱引用通过WeakReference类实现。 弱引用的生命周期比软引用短。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。由于垃圾回收器是一个优先级很低的线程,因此不一定会很快回收弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

应用场景:弱应用同样可用于内存敏感的缓存。

4 虚引用

特点:虚引用也叫幻象引用,通过PhantomReference类来实现。无法通过虚引用访问对象的任何属性或函数。幻象引用仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

ReferenceQueue queue = new ReferenceQueue ();

PhantomReference pr = new PhantomReference (object, queue); 

程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取一些程序行动。


应用场景:可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。


诊断 JVM 引用情况

如果你怀疑应用存在引用(或 finalize)导致的回收问题,可以有很多工具或者选项可供选择,比如 HotSpot JVM 自身便提供了明确的选项(PrintReferenceGC)去获取相关信息,我指定了下面选项去使用 JDK 8 运行一个样例应用:


-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintReferenceGC

这是 JDK 8 使用 ParrallelGC 收集的垃圾收集日志,各种引用数量非常清晰。


0.403: [GC (Allocation Failure) 0.871: [SoftReference, 0 refs, 0.0000393 secs]0.871: [WeakReference, 8 refs, 0.0000138 secs]0.871: [FinalReference, 4 refs, 0.0000094 secs]0.871: [PhantomReference, 0 refs, 0 refs, 0.0000085 secs]0.871: [JNI Weak Reference, 0.0000071 secs][PSYoungGen: 76272K->10720K(141824K)] 128286K->128422K(316928K), 0.4683919 secs] [Times: user=1.17 sys=0.03, real=0.47 secs]


注意:JDK 9 对 JVM 和垃圾收集日志进行了广泛的重构,类似 PrintGCTimeStamps 和 PrintReferenceGC 已经不再存在,我在专栏后面的垃圾收集主题里会更加系统的阐述。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入Java(二):Java中的强引用、软引用、弱引用、幻像引用( 虚引用) 的相关文章

  • 集群环境下的Spring Singleton

    正如中所讨论的this https stackoverflow com questions 1194129 singleton in cluster environmentpost 不适合使用单例聚集的环境 因为不同 JVM 中有多个单例对
  • JVM HotSpot 上的 Java 异常计数器

    我想知道是否可以在不更改应用程序代码的情况下记录 JVM 级别上发生的每个异常 我所说的每个异常是指捕获和未捕获的异常 我想稍后分析这些日志并按异常类型 类 对它们进行分组 并简单地按类型对异常进行计数 我正在使用热点 也许有更明智的理由这
  • 使用 + 符号连接字符串

    今天我在读书Antonio 关于 toString 性能的博客 https antoniogoncalves org 2015 06 30 who cares about tostring performance 还有一段话 昨天曾经被认为
  • STS 无法在我的计算机上启动

    我试图在 eclipse 上设置 Spring mvc 项目 基本项目进展顺利 但是使用 Restful 服务 Jersey 等开始出现许多与依赖项相关的错误 所以我打算转到STS 我正在使用 STS 2 9 2 它给我 无法创建java虚
  • HotSpot使用的Mark-Compact算法是什么?

    当阅读 Mark Compact 章节时垃圾收集手册 https rads stackoverflow com amzn click com 1420082795 提出了一系列替代方案 但其中大多数看起来很旧 理论上 例如 2 指压缩和 L
  • 如何减少Scala中创建的对象数量?

    我正在 Scala 中编写一个计算机图形应用程序 它使用 RGB 类返回图像中某个点的颜色 正如你可以想象的 返回颜色 RGB 对象的函数被调用了很多次 class RGB val red Int val green Int val blu
  • Java 中的引用变量里面有什么?

    我们知道对象引用变量保存表示访问对象的方式的位 它不保存对象本身 但保存诸如指针或地址之类的东西 我正在阅读 Head First Java 第 2 版 一书 书中写道 第 3 章第 54 页 在 Java 中我们并不真正知道什么是 在引用
  • Java 接口合成方法生成,同时缩小返回类型

    我有 2 个接口和 2 个返回类型 interface interfaceA Publisher
  • Scala 中的多个类型下限

    我注意到tuple productIterator总是返回一个Iterator Any 想知道是否无法设置多个下限 因此它可能是最低公共超类型的迭代器 我尝试并搜索了一下 但只发现this https stackoverflow com q
  • 为什么不在下一个 JVM 中删除类型擦除呢?

    Java 在 Java 5 中引入了泛型类型擦除 因此它们可以在旧版本的 Java 上运行 这是兼容性的权衡 我们已经失去了这种兼容性 1 https stackoverflow com questions 22610400 a progr
  • 如何判断我是在 64 位 JVM 还是 32 位 JVM 中运行(在程序内)?

    如何判断应用程序运行的 JVM 是 32 位还是 64 位 具体来说 我可以使用哪些函数或属性来在程序中检测到这一点 对于某些版本的 Java 您可以使用标志从命令行检查 JVM 的位数 d32 and d64 java help d32
  • 测量 tomcat 的排队请求数

    因此 使用tomcat 您可以设置acceptCount值 默认为100 这意味着当所有工作线程都忙时 新连接被放置在队列中 直到队列满 之后它们被拒绝 我想要的是监视此队列中项目的大小 但无法确定是否有办法通过 JMX 获取此值 即不是队
  • 调整 Java 类以提高 CPU 缓存友好性

    在设计java类时 对于实现CPU缓存友好性有哪些建议 到目前为止我学到的是应该尽可能多地使用 POD 即 int 而不是整数 这样 在分配包含对象时 数据将被连续分配 例如 class Local private int data0 pr
  • ASM之前看一下maxStack指令吗?

    我正在尝试使用 ASM 库将字节代码转换为不同的格式 这可以使用 MethodVisitor 来完成 就像这个简单的测试代码一样 return new MethodVisitor ASM7 Override public void visi
  • 如何制作.Net或JVM语言?

    我看到了 NET 和 JVM 的所有这些新语言 一个人如何开始制作一个 我找不到关于 JVM 或 MSIL 规范的任何好的文档 Edit 我已经知道如何解析 我更感兴趣的是如何有这么多人基于这些平台创建新语言 你有点幸运 为 NET 开发的
  • Java:为什么.class文件中的方法类型包含返回类型,而不仅仅是签名?

    class 文件的常量池中有一个 NameAndType 结构 它用于动态绑定 该类可以 导出 的所有方法都被描述为 签名 返回类型 喜欢 getVector Ljava util Vector 当某些 jar 中方法的返回类型发生更改时
  • Dart/Flutter 如何编译到 Android?

    我找不到任何具体的资源 Dart 是否被编译到 JVM 或者 Google 的团队是否编译了 Dart VM 以在 JVM 上运行 然后在 JVM 内的 Dart VM 中运行 Dart 前者更有意义 并且符合 无桥 的口号 但后者似乎更符
  • AtomicInteger 实现和代码重复

    警告 问题有点长 但分隔线以下的部分仅供好奇 Oracle 的 JDK 7 实现原子整数 http docs oracle com javase 7 docs api java util concurrent atomic AtomicIn
  • 如何将 JVM 选项传递给 SBT 以在运行应用程序或测试用例时使用?

    我想在运行我的应用程序或通过 SBT 对应用程序进行测试时指定 JVM 选项 具体来说 我需要能够为 JVM 提供 Djava security policy 参数 以便加载我的策略并用于测试 我怎样才能用 SBT 做到这一点 With x
  • 使用同一类的不同版本进行类加载:java.lang.LinkageError:尝试重复名称的类定义

    我有一个工作代码 可以动态加载具有不同类名的不同类实现 类文件被加载到内存数据库 Apache 德比数据库 类加载器检索 class文件来自BLOB列 我想做的是插入 class文件为带有版本列的二进制 BLOB 和IS ENABLED标志

随机推荐

  • 将div的宽、高按比例设置有什么效果

    在添加div时 对它的大小 宽 高 有两种设置方法 固定值和百分比 1 若div的宽高为固定值 则该div的显示效果会随着其父div的缩放而变化 如下所示 fixed width 200px height 100px background
  • 【C语言】输入三个字符串,比较其大小,最终将它们由大到小输出。利用C指针。

    题目 输入三个字符串 比较其大小 最终将它们由大到小输出 利用C指针 解题思路 定义一个二维字符数组用于存放3组字符串 再定义一个一位指针数组使其分别指向这3个字符串 编写一个函数 利用传入的指针数组 对其指向的字符串的用 选择法 进行排序
  • 函数式接口习题

    基础题 练习一 函数式接口 定义一个函数式接口CurrentTimePrinter 其中抽象方法void printCurrentTime 使用注解 FunctionalInterface 在测试类中定义static void showLo
  • 云解析DNS能为你做什么?

    记录类型 云解析DNS支持A CNAME MX TXT SRV AAAA NS CAA记录类型 您可以参阅 添加解析记录 操作文档 记录类型功能描述AIPV4记录 支持将域名映射到IPv4地址使用AAAAIPV6记录 支持将域名映射到IPv
  • 非printf形式打印各种数据类型的十六进制和二进制

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 一 源码实现 为了适配各种数据类型 且可以通过sizeof得到此类型的大小 所以这里采用模板形式开发 以下是实现此功能的源码
  • 在Ubuntu系统安装jdk1.7步骤

    在Ubuntu12 04系统安装sun jdk1 7 可以到 http www oracle com 下载jdk1 7版本 选择平台Linux x64 Accept the license agreement and download th
  • 《再也不怕elasticsearch》es核心概念

    ES核心概念 大家好我是迷途 一个在互联网行业 摸爬滚打的学子 热爱学习 热爱代码 热爱技术 热爱互联网的一切 再也不怕elasticsearch系列 帅途会慢慢由浅入深 为大家剖析一遍 各位大佬请放心 虽然这个系列帅途有时候更新的有点慢
  • 谷歌浏览器官方下载地址

    谷歌浏览器官方下载地址 在线安装版 https www google com chrome browser desktop index html 离线安装版 https www google com intl zh CN chrome br
  • python编写用户登录程序_python初学之用户登录的实现过程(实例讲解)

    要求编写登录接口 1 输入用户名和密码 2 认证成功后显示欢迎信息 3 用户名输错 提示用户不存在 重新输入 5次错误 提示尝试次数过多 退出程序 4 用户名正确 密码错误 提示密码错误 重新输入 密码错误3次 锁定用户名并提示 退出程序
  • python 字符串替换

    在Python中 字符串是一种非常重要的数据类型 它可以用来表示文本 数字 符号等信息 在实际开发中 我们经常需要对字符串进行替换操作 这时就需要用到字符串替换函数 Python中的字符串替换函数主要有replace translate r
  • 30岁后程序员的出路[转]

    那程序员到了30岁 怎样提高自己的不可替代性呢 我们打算做一辈子程序员吗 敢问路在何方 作为一个过来人 一个资深程序员 我觉得有几个方向可以选择 1 成为技术大拿 其实 做一辈子程序员并没有什么问题 重要的是 你必须成为一个不可替代的程序员
  • 在字节跳动做了6年软件测试,4月无情被辞,想给划水的兄弟提个醒

    先简单交代一下背景吧 某不知名 985 的本硕 17 年毕业加入字节 以 人员优化 的名义无情被裁员 之后跳槽到了有赞 一直从事软件测试的工作 之前没有实习经历 算是6年的工作经验吧 这6年之间完成了一次晋升 换了一家公司 有过开心满足的时
  • [JavaScript] async/await面试题 及其解析

    题目 async function async1 console log 1 await async2 console log 2 async function async2 console log 3 console log 4 setT
  • iframe简单使用 、获取iframe 、获取iframe 元素值 、iframe获取父页面的信息

    文章目录 1 iframe简单使用 2 获取iframe 3 获取iframe 元素值 4 iframe获取父页面的信息 1 iframe简单使用 标签规定一个内联框架 一个内联框架被用来在当前 HTML 文档中嵌入另一个文档 width插
  • 图像分类、目标检测、语义分割、实例分割和全景分割的区别

    1 Image Classification 图像分类 图像分类 下图左 就是对图像判断出所属的分类 比如在学习分类中数据集有人 person 羊 sheep 狗 dog 和猫 cat 四种 图像分类要求给定一个图片输出图片里含有哪些分类
  • ISTQB认证工程师学习笔记(4)——测试技术

    测试技术一般可分为黑盒测试 白盒测试 基于经验的测试技术 黑盒测试 黑盒测试技术 也称为行为的或基于行为的技术 基于对适当测试依据的分析 例如 正式需求文档 规格说明 用例 用户故事或业务流程 这些技术适用于功能和非功能测试 黑盒测试技术关
  • verilog 中的 log2

    对数的作用 log2是指2的对数 对于二进制的计算机系统来说非常有用 比如 10bits的地址线 可寻址的地址空间为2 10 那么反过来对于1024深的地址空间 需要多少bits的地址线 需要用log2 depth 来计算 如何求对数 sy
  • 爬取中国移动用户问答

    最近一个好朋友在搞爬虫 问了很多问题 所以干脆直接写了一个范例 这个程序整体要两次解析网页 第一层是分析网页中的json数据来获取qtid 第二层是用qtid来解析获得问答所在的网页 因为在问答网页里的数据存储是引用的数据库中的数据 所以不
  • Mac系统下algs4学习环境搭建

    InterliJ下的搭建 1 官网下载algs4 rar文件 拷贝到在新建项目的libs文件夹下 然后在File gt project Structure 需要用到啦gs4的模块中导入jar包 这样在程序中引用静态类就不会报错类 termi
  • 深入Java(二):Java中的强引用、软引用、弱引用、幻像引用( 虚引用)

    在Java语言中 除了基本数据类型外 其他的都是指向各类对象的对象引用 Java中根据其生命周期的长短 将引用分为4类 1 强引用 特点 我们平常典型编码Object obj new Object 中的obj就是强引用 通过关键字new创建