JVM—对象已死?
参考资料:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明
在堆里面存放着 Java 世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”。
1、如何判断对象存活
1.1 引用计数法
-
给对象增加一个引用计数器,当对象被引用一次计数器加一、当引用失效时计数器减一
-
任何时候计数器为0的对象就不可能再被使用
这个方法虽然占用一定内存但是原理简单、效率也很高,大多情况都是不错的算法。但Java虚拟机并没有使用这个方法因为这个方法还要考虑很多额外的情况,配合大量处理逻辑才能解决问题。
引用计数法的缺点:
public class ReferenceCountingtGC {public Object instance = null;public static final int _1MB = 1024 * 1024;//这个成员属性的唯一意义就是占点内存,以便在GC日志中看清楚是否回收过private byte[] bigSize = new byte[2 * _1MB];public static void testGC(){ReferenceCountingtGC objA = new ReferenceCountingtGC();ReferenceCountingtGC objB = new ReferenceCountingtGC();objA.instance = objB;objB.instance = objA;//假设在这发生GC,objA和objB能否被回收?System.gc();}
}
-
这两个对象objA和objB已经不可能再被访问了,但是它们因为互相引用对方,导致它们的引用计数都不为零。 所以引用计数算法就无法回收他们
1.2 可达性分析算法
-
这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集。
-
从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”。
-
如果某个对象到GC Roots直接没有引用链就代表这个对象不能被使用。

可作为java中Gc Roots的对象包含哪些?
-
虚拟机栈(栈帧中的局部变量表)中引用的对象。
-
方法区中的静态属性引用对象。(例如被Static修饰的字符串)
-
方法区中常量引用的对象。(例如字符串常量池的引用)
-
在本地方法栈中 JNI(即通常所说的 Native 方法)引用的对象。
-
java虚拟机内部的引用。(例如数据类型对应的Class对象,一些常驻对象(OOM),系统类加载器)
-
所有被同步锁(synchronized 关键字)持有的对象。
-
反映 Java 虚拟机内部情况的 JMXBean、JVMTI 中注册的回调、本地代码缓存等。
2、再谈引用
无论是引用计数法还是可达性分析算法,判断对象是否存活都和对象的引用分不开。
在jdk1.2以后对引用进行了扩充,将引用分为:
-
强引用
-
软引用
-
弱引用
-
虚引用
这四种引用强度依次递减。
2.1 强引用
强引用是最常见的引用类型,是程序代码之间普遍存在的引用赋值,例如这样的引用关系,在任何情况下只要强引用还在JVM就不会回收被引用的对象。
Object obj = new Object();
2.2 软引用
软引用是用来描述一些还有用但非必需的对象。在系统将要发生内存溢出异常之前,这类对象会被列为可回收的资源。在jdk1.2后提供了SoftReference类来实现软引用。
Object obj = new Object();
SoftReference<Object> softReference = new SoftReference<>(obj);
内存不足时,GC会回收软引用指向的对象,以释放空间,避免OutOfMemoryError。
2.3 弱引用
弱引用也用来描述非必需对象,但是其强度比软引用更弱,只能生存到下一次垃圾回收发生之前。使用WeakReference类来实现弱引用。
Object obj = new Object();
WeakReference<Object> weakReference = new WeakReference<>(obj);
GC工作时,无论内存是否足够,都会回收被弱引用关联的对象。
2.4 虚引用
虚引用是最弱的一种引用关系。无法通过虚引用来取得一个对象实例,设置虚引用关联的唯一目的是在这个对象被收集器回收时收到一个系统通知。虚引用PhantomReference必须和引用队列(ReferenceQueue)联合使用。
ReferenceQueue<Object> queue = new ReferenceQueue<>();
Object object = new Object();
PhantomReference<Object> phantomReference = new PhantomReference<>(object, queue);
3、生存还是死亡
真正宣告一个对象的死亡需要至少经历两次标记的过程
1、如果对象进行可达性分析后没有与GC Roots相连的引用链,那么就会被第一次标记
-
接下来将会执行一次筛选,筛选条件是对象是否有必要执行
finalize()方法。(假如对象没有覆盖finalize方法或者finalize方法已经被调用过。虚拟机都会将这两种情况视为没必要执行) -
如果这个对象被判断为有必要执行finalize方法,那么对象将会被放在一个F-Queue队列中。并在稍后由一条虚拟机自动建立的、低调度优先级的Finalize线程去执行它们的Finalize()方法。

2、finalize方法是对象逃脱死亡的最后机会,收集器将会对F-Queue中的对象进行第二次小规模的标记。
-
如果对象要拯救自己,那么需要重新与引用链上的任何一个对象建立关联即可。
-
这种自救的机会只有一次,因为一个对象的 finalize()方法最多只会被系统自动调用一次

4、回收方法区
-
方法区回收的性价比较低
-
方法区主要回收两部分内容:废弃的常量和不再使用的类型。
1、回收废弃常量的条件
-
已经没有任何字符串对象引用常量池的“Java”常量,并且虚拟机中也没有其他地方引用这个字面量。
2、不使用类型的回收条件
-
该类的所有实例都被回收了,也就是Java堆中不存在该类及其任何派生子类
-
加载该类的类加载器已经被回收
-
该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
相关文章:
JVM—对象已死?
参考资料:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明 在堆里面存放着 Java 世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”。 1、如何判…...
【前端面试3+1】20 css三栏布局6种实现方式、多行文本溢出怎么实现、token过期了怎么处理、【二叉树的中序遍历】
一、css三栏布局6种实现方式 1.浮动布局(Floats) .container {overflow: auto; /* 清除浮动 */ }.left, .right {width: 20%; /* 左右栏宽度 */float: left; }.middle {width: 60%; /* 中间栏宽度 */margin: 0 20%; /* 左右栏宽度 */ } 2.Flexbox .conta…...
【C++】vector介绍以及模拟实现(超级详细<=>源码并存)
欢迎来到我的Blog,点击关注哦💕 【C】vector介绍以及模拟实现 前言vector介绍 vector常见操作构造函数iteratorcapacitymodify vector模拟实现存储结构默认构造函数构造函数拷贝构造函数赋值运算符重载析构函数 容量(capacity)si…...
【Redis 进阶】主从复制(重点理解流程和原理)
在分布式系统中为了解决单点问题(某个服务器程序只有一个节点(只搞一个物理服务器来部署这个服务器程序)。可用性不高:如果这个机器挂了意味着服务就中断了;性能 / 支持的并发量比较有限)。通常会把数据复制…...
Git常用命
转自:https://blog.csdn.net/ahjxhy2010/article/details/80047553 1.查看某个文件或目录的修改历史 git log filename #查看fileName相关的commit记录 git log -p filenam # 显示每次提交的diff#只看某次提交中的某个文件变化,commit-id 文件名…...
强化学习时序差分算法之Q-learning算法——以悬崖漫步环境为例
0.简介 基于时序差分算法的强化学习算法除了Sarsa算法以外还有一种著名算法为Q-learning算法,为离线策略算法,与在线策略算法Sarsa算法相比,其时序差分更新方式变为 Q(St,At)←Q(St,At)α[Rt1γmaxaQ(St1,a)−Q(St,At)] 对于 Sarsa 来说&am…...
111推流111
推流推流...
刷题——数组中只出现一次的两个数字
数组中只出现一次的两个数字_牛客题霸_牛客网 描述 一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 数据范围:数组长度 2≤n≤10002≤n≤1000,数组中每个数的大小 0<val≤100000…...
《剖析程序员面试“八股文”:助力、阻力还是噱头?》
#“八股文”在实际工作中是助力、阻力还是空谈? 作为现在各类大中小企业面试程序员时的必问内容,“八股文”似乎是很重要的存在。但“八股文”是否能在实际工作中发挥它“敲门砖”应有的作用呢?有IT人士不禁发出疑问:程序员面试考…...
Redis过期key的删除策略
在 Redis 中,设置了过期时间的键在过期时间到达后,并不会立即从内存中删除。如果不是,那过期后到底什么时候被删除呢? 下面对这三种删除策略进行具体分析。 立即删除: 立即删除能够保证内存数据的及时性和空间的有效…...
软件管理
设备挂载在目录下才可以读 挂载类似于将u盘插在电脑上 mount /dev/sr0 /opt/openeuler/ vim /etc/rc.d/rc.local #开机自运行脚本,将挂载命令写入脚本,并给这个脚本执行权限 chmod x /etc/rc.d/rc.local [rootlocalhost ~]# cd /etc/yum.repos.d/ […...
【2024】Datawhale AI夏令营 Task3笔记——Baseline2部分代码解读及初步上分思路
【2024】Datawhale AI夏令营 Task3笔记——Baseline2部分代码解读及初步上分思路 本文对可完成赛事“逻辑推理赛道:复杂推理能力评估”初赛的Baseline2部分关键代码进行详细解读,介绍Baseline2涉及的关键技术和初步上分思路。 Baseline2代码由Datawhal…...
软件测试——测试分类(超超超齐全版)
为什么要对软件测试进行分类 软件测试是软件⽣命周期中的⼀个重要环节,具有较⾼的复杂性,对于软件测试,可以从不同的⻆度加以分类,使开发者在软件开发过程中的不同层次、不同阶段对测试⼯作进⾏更好的执⾏和管理测试的分类⽅法。…...
深入解析 Go 语言 GMP 模型:并发编程的核心机制
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:点击跳转到网站,对人工智能感兴趣的小伙伴可以点进去看看。 前言 本章是Go并发编程的起始篇章,在未来几篇文章中我们会…...
PHP中如何处理字符串
在PHP中,处理字符串是一项非常常见的任务,PHP提供了大量的内置函数来方便地处理字符串。以下是一些常用的字符串处理函数: strlen() - 返回字符串的长度。 php复制代码 $text "Hello, World!"; echo strlen($text); // 输出&…...
windows内存泄漏检查汇总
VLD(Visual Leak Detector) 下载 官方下载地址2.5 另一分支2.7 安装 点击运行安装...
yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用
yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用 本数据为空中及地面拍摄道路病害检测检测数据集,数据集数量如下: 总共有:33585张 训练集:6798张 验证集:3284张 测试集&a…...
[Meachines] [Easy] Mirai Raspberry树莓派默认用户登录+USB挂载文件读取
信息收集 IP AddressOpening Ports10.10.10.48TCP:22,53,80,1276,32400,32469 $ nmap -p- 10.10.10.48 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.7p1 Debian 5deb8u3 (protocol 2.0) | ssh-hostkey: | 1024 aa:ef:5c:…...
从零开始安装Jupyter Notebook和Jupyter Lab图文教程
前言 随着人工智能热浪(机器学习、深度学习、卷积神经网络、强化学习、AGC以及大语言模型LLM, 真的是一浪又一浪)的兴起,小伙伴们Python学习的热情达到了空前的高度。当我20年前接触Python的时候,做梦也没有想到Python会发展得怎么…...
数据库魔法:SQL Server中自定义分区函数的奥秘
数据库魔法:SQL Server中自定义分区函数的奥秘 在SQL Server中,分区表是管理大型表和提高查询性能的强大工具。分区函数和分区方案允许你根据特定的规则将数据分散到不同的文件组中。本文将深入探讨如何在SQL Server中实现数据库的自定义分区函数&#…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
