JVM的Reference机制

JDK源码解析/深入理解Reference和ReferenceQueue 一、Reference简介1.reference状态Active:新创建的实例状态,当被垃圾收集器回收时,如果实例注册时候指定了队列,则变成Pending状态,否则变成Inactive状态。Pending:pending-Reference列表的一个元素,等待被Reference-handler线程入队。解注册的实例不会是这种状态。Enqueued:实例创建的时候指定的queue的一个元素,当实例... 阅读详情

1.finalizer生产大于消费导致内存溢出测试

User重写了finalize方法的类在创建User对象的同时会创建一个Finalizer对象并加入到Finalizer中以unfinalized为头节点的链表中,当触发GC时如果垃圾收集器判断User对象没有与GCRoot的强引用时则会将Finalizer放到Reference.pending属性上,由线程ReferenceHandler负责处理将Finalizer添加到Finalizer.queue中,然后由线程FinalizerThread负责处理,将Finalizer从Finalizer中以unfinalized为头节点的链表中移除,且调用Finalizer.queue.remove()将Finalizer从Finalizer.queue中移除再执行User中重写的finalize方法再讲Finalizer中的referent属性置空与User切断引用。
此时:
User对象:没有任何引用;
User对应的Finalizer对象:没有任何引用,其各个属性为 next(Finalizer)=this;prev=this;referent=null;queue=ReferenceQueue.NULL;next(Reference)=this; discovered=null;
需要再次触发GC才会回收Finalizer对象和User对象,如果没有触发新的GC则Finalizer对象和User对象会一直存在堆上。

2.WeakReference回收测试(关注pending状态时机)

使用WeakReference添加User引用,当触发GC时如果垃圾收集器判断User对象没有与GCRoot的强引用时将WeakReference放到Reference.pending属性上(此时WeakReference中的referent属性即User已经被回收掉了),由线程ReferenceHandler负责处理将WeakReference添加到创建WeakReference时传入的queue里。由于WeakReference对象本身还没有被回收切被queue强引用着,所以需要手动遍历queue切断WeakReference的强引用(WeakHashMap的原理)。

3.SoftReference回收测试(关注pending状态时机)

使用SoftReference添加User引用,当触发GC时如果垃圾收集器判断User对象没有与GCRoot的强引用,且JVM内存不足时(必须进行fullGC)将SoftReference放到Reference.pending属性上(此时SoftReference中的referent属性即User已经被回收掉了),由线程ReferenceHandler负责处理将SoftReference添加到创建SoftReference时传入的queue里。由于SoftReference对象本身还没有被回收切被queue强引用着,所以需要手动遍历queue切断SoftReference的强引用。

4.WeakReference和finalizer组合测试

当User重写了finalize方法其使用WeakReference添加了User的引用,当User在外部再无强引用时,垃圾回收器会将WeakReference(垃圾回收器将referent置空)和Finalizer放到Reference.pending(WeakReference和Finalizer的处理顺序无法保证,是由垃圾回收器决定的,不同垃圾回收器可能不一致)属性上,由ReferenceHandler进行处理,后续过程与1、2一致;

5.PhantomReference虚引用回收测试(关注pending状态时机和Cleaner测试)

// TODO待补充

Reference中存在Active/活跃状态、Pending/等待状态、Enqueued/已入列状态(排队状态)、Inactive/不活跃状态四种状态

Active

当Reference对象刚刚被创建且没有发生GCROOT检查时。
此时Reference各个属性状态:
referent=User对象
queue=创建Reference时传入的ReferenceQueue,未传入为ReferenceQueue.NULL
next=null
discovered=null
static pending=null

Pending

当触发可达性分析对对象进行GCRoot检测时,垃圾回收器会关注全部的Reference对象将referent属性GCRoot状态发生变化(不同的引用类型定义不同)的Reference放到一个队列A里,垃圾回收器遍历队列对Reference进行指定操作(不同的引用类型定义不同),并把Reference实例放置到Reference.pending属性上(静态),将队列中的下一个Reference实例放到当前Reference的discovered属性上,next赋值为this。

referent属性GCRoot状态发生变化(不同的引用类型定义不同):WeakReference和PhantomReference和FinalReference是referent没有强引用时;SoftReference是referent没有强引用且内存不足时。

指定操作(不同的引用类型定义不同):WeakReference和SoftReference和PhantomReference 将referent置为null并回收User;FinalReference不做特殊处理。

此时Reference各个属性状态:
referent= WeakReference和SoftReference和PhantomReference时referent=null;FinalReference时referent=User;
queue=创建Reference时传入的ReferenceQueue,未传入为ReferenceQueue.NULL
next=this/A[x]
discovered=A[x].next;
static pending=A[x]

Enqueued

Reference中有一个ReferenceHandler线程负责异步处理垃圾处理器放到Reference.pending上的Reference实例,如果这个Reference在创建时有传入ReferenceQueue即Reference.queue!=ReferenceQueue.NULL则将Reference实例添加到创建时传入的ReferenceQueue中。
此时Reference各个属性状态:
referent= WeakReference和SoftReference和PhantomReference时referent=null;FinalReference时referent=User;
queue=ReferenceQueue.ENQUEUED
next=上一个添加到创建时传入的ReferenceQueue中的Reference实例
discovered=null;
static pending=this.discovered;

Inactive

当调用创建Reference时传入的ReferenceQueue的poll()或者remove()方法时(一般定时调用ReferenceQueue的poll方法获取Enqueued状态的Reference来做对应处理),Reference会变为Inactive状态;即意味着此引用对象可以被回收,并且对内部封装的对象也可以被回收掉了。
此时Reference的各个属性状态:
referent= WeakReference和SoftReference和PhantomReference时referent=null;FinalReference时referent=null(Finalizer线程会显式置空referent);
queue=ReferenceQueue.NULL
next=this;
discovered=null;
static pending=此属性为静态属性可能受其他Reference和垃圾回收器影响变化。

JVM的Reference中的queue和pending等属性以及四种状态机制主要目的是用于JVM垃圾回收器线程和用户线程之间的通信,要知道线程通信的两种手段是共享内存和消息传递,JVM线程明显不能给用户线程发送消息,所以这是一种共享内存机制。JVM的垃圾回收器线程会操作pending属性将referent属性GCRoot状态发生变化的Reference实例放到pending属性上,在java中有一个线程ReferenceHandler对pending属性进行轮询监控处理放入queue中,然后用户线程可以通过变量queue获取到GC线程的通知。

JNDI注入原理详解:RMI与LDAP利用链及防御实践 在Java应用开发中,命名与目录服务是连接业务逻辑与底层资源的桥梁,而JNDI(Java命名和目录接口)正是这套机制的核心规范。它本质上是将对象绑定到名称,供应用通过lookup方法获取,类似DNS解析域名。然而,当lookup参数被外部控制时,攻击者可借助RMI或LDAP协议构造恶意引用,诱导JVM远程加载类并执行代码,形成JNDI注入。理解其原理不仅有助于剖析fastjson、Log4j2等组件中反复出现的远程代码执行漏洞,也能在面对如org.springframework.ldap.nopermiss 阅读详情

相关推荐

【嵌入式面经】上海 70迈 线上笔试

“关注|点赞|收藏” 福利干货第一时间送达!最近在做免费的嵌入式知识分享,帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作!

qq_56921854的博客 1134

详解java中Reference的实现与相应的执行过程

一、Reference类型(除强引用) 可以理解为Reference的直接子类都是由jvm定制化处理的,因此在代码中直接继承于Reference类型没有任何作用.只能继承于它的子类,相应的子类类型包括以下几种.(忽略没有在java中使用的,如jnireference) SoftReference WeakReference FinalReference ...

maso88的专栏 613

UE4_用户控件_6_通过控件蓝图内部变量来修改进度条的值

发现控件类图类的引用和用户控类引用不兼容,修改变量类型。我们需要添加到视口,同时设置输入模式。创建按钮的点击事件,当点击时调用角色的自定义事件clearwidget。可以了,但是没有退出控件,没有鼠标,所以改进一下。

Growthofnotes的博客 1236

Java ~ Reference ~ ReferenceQueue【源码】

如果一个Reference(引用)类对象注册了ReferenceQueue(引用队列)类对象,且其所指对象被GC判定为可回收,则该Reference(引用)类对象会被置入ReferenceQueue(引用队列)类对象中(这里是简单叙述,实际上将Reference(引用)类对象加入引用队列还是有一个过程的,这个过程被称为Reference(引用)机制)。

说淑人的所思所想 1431

易灵思FPGA-软件Efinity和Modelsim联仿设置

文章目录前言一、modelsim破解过程二、使用步骤1.引入库2.读入数据总结欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智

qq_35221855的博客 5358

STM32驱动WS2812B实现音乐频谱可视化系统

本文详细介绍了基于STM32驱动WS2812B灯带实现音乐频谱可视化系统的设计与实现。通过FFT算法实时分析音频信号,将频谱映射到炫彩灯光控制系统,结合PWM和DMA技术实现低延迟响应。系统支持多模式切换和动态亮度调节,适用于创意灯光秀和智能家居场景。

weixin_29171129的博客 301

JVM学习笔记-引用(Reference)机制

如果你还不了解JVM的基本概念和内存划分,请阅读JVM学习笔记-基础知识和JVM学习笔记-内存处理文章。 因为Java中没有留给开发者直接与内存打交道的指针(C++指针),所以如何回收不再使用的对象问题,就丢给了JVM。所以接下来就介绍一下目前主流的垃圾收集器所采用的算法。不过在此之前,有必要先了解Reference        1.引用(Reference) 如果你现在还是JDK1.0或

Inspiration 2449

基于DFT的scanshift sdc模板(DFT)

摘要:本文详细介绍了DFT测试模式下的SDC约束方法。

murphyrong的博客 882

java 引用机制_Java引用机制——reference

所谓引用传递就是指将堆内存空间的使用权交给多个栈内存空间。例子<1>public class Aliasing {int temp = 30;public static void main(String[] args) {// TODO 自动生成的方法存根Aliasing d1 = new Aliasing();d1.temp = 50;System.out.println(d1.te...

weixin_39959615的博客 236

《UDS协议从入门到精通》系列——图解0x19:读取故障码信息

认识最核心的诊断服务“0x19”!!全网最强图解!一文搞懂所有常用子服务!

车载系统攻城狮 1万+

手把手教你学Simulink--进阶电机控制场景实例:基于Simulink的直流电机双闭环调速系统抗负载扰动仿真

摘要:本文基于Simulink平台构建直流电机双闭环调速系统,重点研究其在工业传送带场景下的抗负载扰动性能。系统采用转速外环(稳速)和电流内环(限流)的嵌套结构,通过工程法整定PI参数,实现了转速跌落<10%、恢复时间<0.5s的优异抗扰性能。仿真结果表明,相比单闭环系统,双闭环控制使转速跌落率降低47%,恢复时间缩短75%。文中详细介绍了数学模型建立、Simulink模块实现及参数优化方法,并提供了完整代码和模型文件,为电机控制系统设计提供实用参考。

MHD0815的博客 179

jvm内存JVM学习笔记-引用(Reference)机制

在写这篇文章之前,xxx已经写过了几篇关于改jvm内存主题的文章,想要了解的朋友可以去翻一下之前的文章 如果你还不了解JVM的基本概念和内存划分,请阅读JVM学习笔记-基础知识和JVM学习笔记-内存处理文章。 因为Java中没有留给开发者直接与内存打交道的指针(C++指针),所以如何回收不再应用的对象问题,就丢给了JVM。所以接下来就介绍一下目前主流的垃圾收集器所采取的算法。不...

weixin_30508309的博客 140

移动端实战指南:深入理解 & 接入 IAB OMSDK

OMSDK(OpenMeasurementSDK)是IABTechLab推出的标准化测量工具,用于统一移动端/原生App广告的可见性和验证流程。其核心包括Native库(采集设备数据)和OMID JavaScript层(实现通信),通过标准化接口让开发者只需接入一套SDK即可兼容多个测量厂商,减少冲突和性能损耗。v1.4版本强化了对CTV和原生App场景的支持,而v1.5新增了画中画检测等功能。集成流程需通过IAB技术实验室注册下载,并遵循严格的命名空间规则。测试阶段需嵌入验证脚本并通过指定工具验证

帅次的博客 1184

GraalVM Reference Manuals 技术指南:JVM 编译器、多语言嵌入与安全机制全景解析

GraalVM 官方参考手册(Reference Manuals)为已经使用或正在评估 GraalVM 的软件工程师提供了各核心技术的深度文档,覆盖 GraalVM 作为 Java 虚拟机的运行时模型、Graal JIT 编译器、多语言嵌入(Embedding)、跨语言互操作(Polyglot)、Truffle 语言实现框架以及安全模型。本文将这份手册作为主线,逐章展开其核心内容,并结合当前仓库(

gitblog_00379的博客 497

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

JVM 学习笔记

《深入理解JVM虚拟机》读书笔记 reference 的两种实现 ​ 创建对象自然是为了后续使用该对象,我们的 Java 程序会通过栈上的 reference 数据来操作堆上的具 体对象。由于 reference 类型在《Java 虚拟机规范》里面只规定了它是一个指向对象的引用,并没有定义 这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实 现而定的,主流的访问方式主要有使用句柄和直接指针两种: 使用句柄 如果使用句柄访问的话,Java 堆中将可能会划分出一块内存来

CComma 494

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

JVM 深入笔记(3)垃圾标记算法

JVM深入笔记(3)垃圾标记算法Author: PoechantBlog: blog.youkuaiyun.com/PoechantEmail: zhongchao.ustc#gmail.com (#->@)Date: March 3rd, 2012Copyright © 柳大·Poechant如果您还不了解 JVM 的基本概念和内存划分,请先阅读《JVM 深入笔记(1)内存区域是如何划分的?》一文。然后再回

麦克船长的技术笔记 7191

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java编程开发之浅析Java引用机制

不难发现,Reference机制对JVM的垃圾收集活动敏感,Reference的继承关系或者实现是由JDK定制,引用实例是由JVM创建,一般不推荐自行继承Reference实现自定义的引用类型,但是可以继承已经存在的引用类型。JDK提供了强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference),引用队列(ReferenceQueue)以及析构引用(Final Reference)等引用类型。

pingguocu3的博客 1003

资料收集&转载

Lambda 1)Lambda表达式增强版Comparator和排序 http://www.importnew.com/15259.html 2)Java 8 中的 Streams API 详解 https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/ 3)特殊实例  List转Map:指定任意字段组合成主键 Map<S...

cjjcode 144

Apache MXNet Scala/Java 绑定 JVM 内存管理完全指南:ResourceScope 与原生内存释放机制解析

本文面向使用 Apache MXNet Scala/Java 绑定的开发者,系统讲解 JVM 与 C++ 原生内存的边界问题,以及 MXNet 提供的三种内存管理模式(`ResourceScope.using`、Phantom Reference 自动回收、手动 `dispose`)的原理、适用场景与最佳实践。读完本文,你将掌握如何在训练循环、推理服务等场景下正确释放 NDArray、Symbol

gitblog_00865的博客 442

运行Hello World 程序会启动几个线程

运行Hello World 程序会启动几个线程?学习 java基础 – 线程 博客时遇到的问题:一个最简单的打印HelloWorld的程序,说说看,运行这个应用,Java至少会创建几个线程呢?

fengdongnan的博客 905

Java引用类型

JVM的垃圾收集机制通过可达性分析算法判断对象是否存活,主要依据对象与GC Roots的引用链。Java引入了四种引用类型:强引用、软引用、弱引用和虚引用,以提供更灵活的内存管理。强引用对象不会被GC回收,而软引用和弱引用对象在内存不足时会被回收,虚引用对象则在下一次GC时被回收。这些引用类型通过java.lang.ref.Reference<T>及其子类实现,与GC协同工作,确保内存的高效使用。引用实例在JVM中有四种状态(Active、Pending、Inactive、Enqueued),状

qj19842011的专栏 1078

Play Framework 生产环境配置完全指南:通用配置、日志与 JVM 调优

生产环境中的 Play Framework 应用,其行为主要通过三类配置来控制:**通用配置**(数据库连接、应用密钥、HTTP 端口、SSL 等)、**日志配置**(logback)与 **JVM 配置**。本文基于 Play Framework 官方生产配置文档,结合仓库内 `play-server`、`play-pekko-http-server`、`play-netty-server` 的

gitblog_00258的博客 385

【JVM原理详解】19-对象访问定位-句柄与直接指针

对象创建后,Java 程序需要通过栈上的引用(reference)去操作堆中的对象。但"引用"到底如何定位到堆中的对象?。不同的访问方式在 GC 稳定性和访问性能之间做出不同权衡。本篇将讲解两种主流的对象访问方式——和,分析它们各自的优劣,以及主流 JVM 的实现选择。

gaochufukanyongren的博客 339

Java的java.lang.StackWalker中的影响性能

尽管其设计初衷是为了替代传统的Throwable.getStackTrace()方法以提升性能,但在实际使用中,StackWalker的性能表现仍受多种因素影响。启用这些选项会增加额外的开销,例如保留类引用会导致JVM维护更多的元数据,而显示隐藏帧(如Lambda生成的帧)会扩大栈遍历范围。在高性能场景中,建议明确指定需要分析的栈层数,减少不必要的帧解析。如果通过StackWalker访问的栈帧涉及反射调用(如Method.invoke),JVM可能无法完全优化栈遍历路径,导致性能下降。

ihbvpl_252的博客 246
上一篇: 进程地址空间和虚拟内存
下一篇: 从网线到IO模型(网络基础整合)
躺平程序猿
博客等级 码龄8年 4870粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

躺平程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值