你搞得懂JVM垃圾回收机制?

【JVM】一文掌握JVM垃圾回收机制 作为Java程序员,除了业务逻辑以外,随着更深入的了解,都无法避免的会接触到JVM以及垃圾回收相关知识。JVM调优是一个听起来很可怕,实际上很简单的事。 感到可怕,是因为垃圾回收相关机制都在JVM的C++层实现,我们在Java开发中看不见摸不着;而实际很简单,是因为它说到底,也只是JVM替我们实现的垃圾对象回收机制,也是普通的程序代码,只要理解了垃圾回收器的底层设计思想,掌握JVM调优并非难事! 阅读详情

一、回收堆区

垃圾回收器在堆进行垃圾回收前,首先要判断这些对象那些还存活,那些已经“死去”。判断对象是否已“死”有如下几种算法:

1.引用计数法

给对象增加一个引用计数器,每当有一个地方引用它时,计数器就+1;

当引用失效时,计数器就-1;

任何时刻计数器为0的对象就是不能再被使用的,即对象已“死”。

引用计数法实现简单,判定效率也比较高,在大部分情况下都是一个比较好的算法。

但是,在主流的JVM中没有选用引用计数法来管理内存,最主要的原因是引用计数法无法解决对象的循环引用问题。

2. 可达性分析算法

在上面讲了,Java并不采用引用计数法来判断对象是否已“死”,而采用“可达性分析”来判断对象是否存活。

通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为“引用链”,当一个对象到 GC Roots 没有任何的引用链相连时(从 GC Roots 到这个对象不可达)时,证明此对象不可用。以下图为例:

在Java语言中,可作为GC Roots的对象包含以下几种:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象。
  2. 方法区中静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中(Native方法)引用的对象

引用

在JDK1.2以前,Java中引用的定义很传统: 如果引用类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。

这种定义有些狭隘,一个对象在这种定义下只有被引用或者没有被引用两种状态。

在JDK1.2之后,Java对引用的概念做了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)四种,这四种引用的强度依次递减。

1.强引用

类似于"Object obj = new Object()"这类的引用,只要强引用还存在,垃圾回收器永远不会回收掉被引用的对象实例。

当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。

2.软引用

如果一个对象只具有软引用,那就类似于可有可无的生活用品。

如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。

软引用可用来实现内存敏感的高速缓存。

举例:查看网页,可能后退,那么刚才的网页要不要一直存储,一直存储就是强引用,不存储就是回收,那么折中一下,于是产生了弱引用,当内存空间足够时,就不回收,不足时,再回收。这个根据内存敏感程度而变化而决定是否缓存,就是内存敏感的高速缓存。

3.弱引用

对象拥有更短暂的生命周期。

在gc线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间是否充足,都会回收它的内存。

由于gc是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

4.虚引用

就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

作用: 虚引用主要用来跟踪对象被垃圾回收的活动

区别: 虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。

如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

3.真正判决

要宣告一个对象的真正死亡,至少要经历两次标记过程

如果对象在进行可达性分析之后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选。

筛选的条件是此对象是否有必要执行finalize()方法。

没必要:没有覆盖finalize()方法 或 finalize()方法已经被调用过一次了

审判

如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会被放置在一个叫做F-Queue的队列之中,并在稍后由一个虚拟机自动建立的、低优先级的Finalizer线程去执行它

如果对象在finalize()中成功拯救自己:与引用链上的任何一个对象建立起关联关系

那在第二次标记时它将会被移除出"即将回收"的集合,也就暂时逃脱死亡的命运了。

如果对象这时候还是没有逃脱,那基本上它就是真的被回收了。

二、回收方法区

方法区(永久代)的垃圾回收主要收集两部分内容:废弃常量和无用类。

废弃常量:

没有任何一个String对象引用常量池中的"abc"常量,也没有其他地方引用这个字面量,如果此时发生GC并且有必要的话,这个"abc"常量会被系统清理出常量池。

常量池中的其他类(接口)、方法、字段的符号引用也与此类似。

无用类

1.该类的所有实例都已经被回收(即在Java堆中不存在任何该类的实例)
2.加载该类的ClassLoader已被回收 3.该类对应的Class对象没有任何其他地方被引用,无法在任何地方通过反射访问该类的方法

三、垃圾回收算法

1.标记-清除算法

首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象

“标记-清除”算法的不足主要有两个

  1. 效率问题:标记和清除这两个过程的效率都不高
  2. 空间问题:标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行中需要分配较大对象时,无法找到足够连续内存而不得不提前触发另一次垃圾收集。

2.复制算法(新生代回收算法)

它将可用内存按容量划分为大小相等的两块,每次只使用其中一块。

当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另一块上面,然后再把已经使用过的内存区域一次清理掉。

因为复制过去后,另一边的内存肯定是连续的了,此时再把使用过得内存区域清理,从而达到了整理的效果。

也就是伊甸园区移动到survive0和survive1区的算法。

但是,伊甸园区的对象都是朝生夕死的,所以并不需要1:1的空间,所以出现了8:1:1的默认比例

3.标记整理算法(老年代回收算法)

复制收集算法在对象存活率较高时会进行比较多的复制操作,效率会变低。因此在老年代一般不能使用复制算法。

而是采用标记整理算法

标记过程仍与“标记-清除”过程一致,但后续步骤不是直接对可回收对象进行清理,而是让所有存活对象向一端移动,然后直接清理掉除存活对象以外的内存。流程图如下:

4.分代收集算法

就是将堆区分开,不同的位置采用不同的算法

在新生代中,每次垃圾回收都有大批对象死去,只有少量存活,因此我们采用复制算法;

而老年代中对象存活率高,就必须采用"标记-清理"或者"标记-整理"算法。

四 .Minor GC、Major GC、Full GC的区别?

Minor GC 又称为新生代GC 指的是发生在新生代的垃圾回收操作(包括Eden区和Survivor区)。

当年轻代内存空间被用完时,就会触发垃圾回收。这个垃圾回收叫做Minor GC。

Major GC通常是跟full GC是等价的,收集整个GC堆。

但因为HotSpot VM发展了这么多年,外界对各种名词的解读已经完全混乱了

Full GC定义是相对明确的,就是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。

针对HotSpot VM GC来看

它里面的GC其实准确分类只有两大种:

Partial GC:并不收集整个GC堆的模式

  • Young GC:只收集年轻代的GC
  • Old GC:只收集老年代的GC。只有CMS的concurrent collection是这个模式
  • Mixed GC:收集整个年轻代以及老年代的GC。只有G1有这个模式

Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。

JVM内存模型及垃圾回收机制 JVM内存模型 在JVM运行的时候所分配内存区的结构,分为程序计数器、虚拟机栈、本地方法栈、堆和方法区五部分。JVM占用的内存分为线程共享区 和线程私有区,线程共享区和JVM同生共死,所有线程均可访问此区域;而线程私有区顾名思义每个线程各自占有,与各自线程同生共死。 方法区:用于存储类信息、常量池、静态变量、JIT编译后的代码等数据,具体放在哪里,不同的实现可以放在不同的地方。 堆:Java堆是Java虚拟机所管理的内存中中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。 阅读详情

相关推荐

JVM垃圾回收机制

1.什么是垃圾回收机制 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制。 2.什么时候进行垃圾回收 ①会在cpu空闲的时候自动进行回收   ②在堆内存存储满了之后   ③主动调用System.gc()后尝试进行回收 补充:System.gc()用于调用垃圾收集...

zhangxing 3万+

使用软引用构建敏感数据的缓存

[align=center][size=large]使用软引用构建敏感数据的缓存[/size][/align] 一、实现原理 1.应用场景 查询频率较高的数据;每次查询均需要通过接口与数据库交互,构建对象仍需要占用一部分内存;即便上次查询的结果仍在内存中还未被GC回收但仍需要再次进行相同的查询操作; 将查询结果放入内存--大量占用内存空间,增加发生内存溢出的可能; 每次都重新查询...

走在命运的左岸 446

STM32 HAL库驱动BMP388:从寄存器配置到高精度气压温度采集

本文详细介绍了如何使用STM32 HAL库驱动BMP388气压温度传感器,实现高精度数据采集。内容涵盖从硬件连接到STM32CubeMX配置、关键寄存器解析、驱动源码编写,到核心补偿算法与海拔换算的完整流程,并提供了针对不同应用场景的优化配置与调试技巧,帮助开发者快速构建稳定可靠的测量方案。

weixin_29299807的博客 171

一文彻底搞懂JVM垃圾回收机制

CMS 使用的是标记-清除的算法实现的,所以在 gc 的时候回产生大量的内存碎片,当剩余内存不能满足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会被降低。在做 Java 开发的过程中,我们会不断地创建很多的对象,这些对象数据会占用系统内存,如果得不到有效的管理,内存的占用会越来越多,甚至会出现内存溢出的情况,所以,我们需要进行对内存进行合理地释放,这个时候 GC 就派上大用场的。

永远在路上 1582

Workbench中基于nCode的列车转向架随机振动疲劳寿命预测方法

本文详细介绍了在ANSYS Workbench中结合nCode进行列车转向架随机振动疲劳寿命预测的完整方法。通过几何清理、模态分析、PSD载荷定义及随机振动求解,并重点阐述了nCode中Dirlik等疲劳算法的选择与应用,为轨道交通关键部件的可靠性设计提供了系统的仿真分析流程与工程实践指导。

weixin_29234423的博客 474

Windows下用MSYS2一键搞定Verilator安装(附国内镜像加速)

本文详细介绍了在Windows系统下,如何利用MSYS2工具和国内镜像源,快速、高效地完成Verilator的安装与配置。通过替换清华镜像源加速下载,并配合Pacman包管理器,实现近乎一键式的安装流程,有效解决了传统方法步骤繁琐、网络依赖下载慢的问题,为数字电路仿真提供了便捷的Windows环境解决方案。

weixin_29208327的博客 596

内存缓存(in-memory cache)

内存缓存(in-memory cache) 当建立一个大型Java应用时,引起性能问题大部分是延迟,延迟是指请求和响应之间的时间差,在一个分布式Java系统中引起延迟的原因有: 从磁盘上加装数据的IO延迟 跨网络加装数据的IO延迟。 在分布式锁上的资源争夺。 垃圾回收引起的暂停。 典型Ping时间是:本地机器是57µs;局域网是300 µs;从伦敦到纽约是100ms;对于1Gb网络,网络数据传...

qinheJ的博客 1251

【雷达图】R语言绘制雷达图(ggradar),NBA季后赛数据为例

一起用R语言给nba球星画球技雷达图吧!

池塘春草梦的博客 6252

【JVM垃圾回收(GC)机制(一文读懂)】

垃圾回收器GC(垃圾回收)的垃圾回收算法、垃圾回收器、运行时数据区详解

weixin_44985305的博客 1483

代码解读:使用Stable Diffusion完成相似图像生成任务

作为内容生产重要的一部分,生成相似图像是一项有意义的工作,例如很多内容创作分享平台单纯依赖用户贡献的图片已经不够了,最省力的方法就是利用已有的图片生成相似的图片作为补充。这篇博客详细解读基于Stable Diffusion生成相似图片的原理和代码。

沉迷单车的追风少年 1394

2025年“区块链技术”职业院校技能大赛赛后复盘与总结(必看)

记录一次2025年“区块链技术”职业院校技能大赛的参加经验总结与赛后复盘

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 1994

JVM专题七:JVM垃圾回收机制

中,我们介绍了JVM内存主要分哪些区域,这些区域分别是干什么的,同时也举了个例子,在运行过程种各个区域数据是怎样流转的。细心的小伙伴可能发现一个问题,在介绍完方法弹栈以后就没有介绍后续流程了。方法执行完以后,堆内存存放的对象实例咋整呢,带着这样的疑问进入今天的内容。

Jeremy程序员 2万+

用业务语义织就企业数据之网:SAP Datasphere 的定位、架构与落地场景全解析

SAP Datasphere作为SAP业务数据云的核心组件,通过语义层整合企业内外部数据,支持实时分析与AI应用。其核心功能包括数据集成、语义建模、虚拟化与仓库能力,通过Spaces实现资源隔离,Data Builder和Business Builder分别面向技术和业务建模。该平台与SAP HANA Cloud、SAC等深度集成,支持财务统一分析、供应链可视化等典型场景,并可通过BW bridge实现传统BW资产云化迁移。Datasphere强调开放互联,能与Databricks等生态伙伴协同,为企业提供

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1366

JVM 的垃圾回收机制以及垃圾回收算法的详解

引入了“对象的年龄”这样的概念,JVM 中有专门的线程负责周期性扫描/释放,一个对象如果被线程扫描一次,并且“可达性分析”证明可达(不是垃圾),此时将该对象的年龄属性 + 1(初始年龄为0)。然后经过一轮 GC 扫描后,会有少数存活的对象通过“复制算法”拷贝到生存区(有两个生存区),后续的 GC 扫描线程会对伊甸区和生存区都进行扫描,伊甸区中少数存活的对象同样会进入生存区,而生存区中仍然存活的对象会拷贝到另外一个生存区。

Hacynn的博客 2691

基于强化学习控制策略的三相逆变器仿真

强化学习控制器的核心在于定义状态空间、动作空间、奖励函数以及选择合适的强化学习算法(例如DQN、DDPG等)。对于三相逆变器,状态可以是输出电压、电流等信息;动作则可能是调制指数的变化量;奖励函数则应鼓励快速准确地跟踪参考信号。定义状态空间和动作空间状态空间可以包括逆变器的输出电压、电流及其变化率等信息。动作空间则是控制器可执行的动作,例如PWM信号的调整幅度。matlab深色版本% 定义状态和动作空间维度numObs = 6;% 假设有六个状态变量(例如三相电压和电流)

amy_mhd的博客 137

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

深入理解 JVM 的垃圾回收机制

本篇内容我们从头到尾讲了一遍 JVM 的垃圾回收机制,包括垃圾回收的概念、垃圾判断算法、垃圾收集算法、Stop The World、新生代和老年代等等。 记得以前有这样一副动图,用来嘲笑 JVM 的垃圾回收机制,大致的意思就是,JVM 的垃圾回收机制很工业化,但是好像是在做无用功,垃圾回收不彻底。

在技术的广袤天地里,本博客如精准罗盘。剖析前沿科技,深掘代码奥秘,以精炼笔触,带您穿越复杂技术迷宫,速达知识彼岸。 1587

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

JVM垃圾回收机制详解

JVM垃圾回收机制是Java自动管理内存的核心功能,通过"内存管家"式的运作方式自动清理不再使用的对象。其工作流程包括标记存活对象、清除垃圾对象和可选的内存整理三个阶段。垃圾回收器采用分代收集理论,将堆内存分为年轻代(使用复制算法)和老年代(使用标记-整理或标记-清除算法)。常见的垃圾回收器包括单线程的Serial收集器、并行工作的Parallel收集器,以及减少停顿时间的CMS和G1收集器。理解垃圾回收机制有助于开发人员优化内存使用,避免内存泄漏和性能问题,是编写高效Java程序的重要

从不水文,坚持创作,加油 1327

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【JVM】JVM垃圾回收机制GC

JVM的垃圾回收机制(Garbage Collected, GC)主要是针对堆内存消亡的对象的回收和内存分配。该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。垃圾收集算法包括:标记-清除算法、标记-复制算法、标记整理算法、分代收集。标记算法用于确定哪些对象是可以被回收的,标记出堆内存中可被回收的对象。引用分为强引用、软引用、弱引用、虚引用四种(引用强度逐渐减弱)该类所有的实例都已经被回收,也就是堆中不存在该类的任何实例。

RiceVan的博客 3190

JVM的垃圾回收机制

摘要:垃圾收集器(GC)通过可达性分析和引用计数算法判定对象存活状态,采用分代收集策略进行内存回收。新生代使用复制算法(Serial/ParNew/ParallelScavenge),老年代采用标记-清除/整理算法(SerialOld/ParallelOld/CMS)。G1收集器创新性地采用Region分区和优先级回收机制,兼顾吞吐量与低延迟。GC触发条件包括堆内存不足和系统空闲时,回收过程可能导致STW。JDK8垃圾收集器默认使用ParallelScavenge+ParallelOld组合。

cxbtdd的博客 1973

JVM 垃圾回收机制:GC

JVM的垃圾回收机制:GC,是Java提供的对于内存自动回收的机制。

m0_60462557的博客 2696

JVM垃圾回收机制(GC)

在新生代中,由于对象的存活率较低,复制算法被广泛应用,一般会将新生代分为一块较大的Eden区和两块较小的Survivor区(通常比例为8:1:1),大部分对象在Eden区中创建,当Eden区满时,会将存活对象复制到其中一个Survivor区,另一个Survivor区作为备用。这是最基础的垃圾回收算法。在清除阶段,回收器扫描整个堆内存,回收所有未被标记的对象,即垃圾对象。G1收集器是JDK 7u4之后引入的一个全新的垃圾收集器,它是一款面向服务端应用的垃圾收集器,在多CPU和大内存的场景下有很好的性能表现。

m0_74404191的博客 2210

【JVM】JVM的垃圾回收机制与垃圾回收器的选择

初步探讨JVM的垃圾回收机制,包括其工作原理、如何确定对象回收、可用的垃圾回收器以及如何进行垃圾回收器的选择与配置

JCoder的博客 1323

简述JVM中的垃圾回收机制

简述JVM中的垃圾回收机制 (一)概述 JVM垃圾回收机制是面试的重点也是难点,只要问到JVM,那么垃圾回收是必问的。JVM垃圾回收算法主要的几个核心点包括垃圾识别机制,垃圾回收算法,有时候也需要了解当今商用JVM使用的几种垃圾收集器和他们之间的区别。 我们先来了解一下GC。 java相较于c、c++语言的优势之一是自带垃圾回收器,程序开发人员不用手动管理内存,内存的分配和释放完全由GC(Garbage Collector)来做,极大地提高了软件开发效率及程序健壮性(手动管理内存容易造成内存泄漏)。凡事皆有

物是人非,结局始终不美 7245
上一篇: 讲讲Docker容器间网络互联原理
下一篇: Java 适配器模式
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值