Full GC为什么那么慢?为什么老年代垃圾回收效率比新生代低很多?为什么Minor gc速度比Major GC慢?

2024-01-01 20:32

本文主要是介绍Full GC为什么那么慢?为什么老年代垃圾回收效率比新生代低很多?为什么Minor gc速度比Major GC慢?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GC类型分为三种:

Yong GC

Old GC

MIXED GC

Full GC

(有些文章和书上也叫Minor GC、Major GC、Full GC,由于Major GC的意思有些混淆,所以改成Old GC容易理解)


GC回收的“无用的类”(元数据区):
1、该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例
2、加载该类的 ClassLoader已经被回收
3、该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法


JVM性能调优主要目的是避免Full GC的发生

Full GC的慢,其实是相对于Yong GC和Old GC。


Yong GC回收新生代

Old GC回收年老代,个别JVM参数配置设置了Old GC之前必须执行一次Yong GC

MIXED GC回收新生代+老年代,G1回收算法

Full GC回收新生代、老年代、元数据区/永久代


Full GC为什么那么慢?

1、元数据区的回收算法效率低,虚拟机规范Class回收条件比较苛刻


2、Full GC回收新生代、老年代、元数据区/永久代。从这个角度讲,多回收了方法区,增加了总的回收耗时。(有些文章提到Full GC能回收堆外直接内存,这个说法并不准确,本质上是JVM一个后台线程,通过虚引用遍历堆里已经被回收的对象对直接内存的直接引用,显示的调用free()方法释放直接内存,Full GC不能直接释放堆外直接内存。总之,堆外直接内存的释放,和GC方式类型无关)


3、Full GC本身不会先进行Minor GC,我们可以配置-XX:+ScavengeBeforeFullGC(非CMS回收算法)、CMSScavengeBeforeRemark(CMS回收算法)可以,让Full GC之前先进行一次Minor GC,因为老年代很多对象都会引用到新生代的对象,先进行一次Minor GC可以提高老年代GC的速度。

(G1回收算法除外,G1回收有一个MIXED回收阶段,新生代和老年代都一起回收,与配置的JVM参数无关)


4、CMS发生了concurrent mode fail,young区使用ParNew(并行GC),Old+Perm(单独设置)使用CMS,整个堆(young+old+metaspace/perm)使用MSC(Mark Sweep Compact)是CMS GC算法的Full GC算法,单线程回收整个堆,回收过程有严格的步骤,碎片压缩,它是单线程的标记-压缩收集器,所以耗时非常的长。

(单线程、碎片压缩,由于并发失败,不能继续并发回收,STOP-THE-WORD回收效率是必要的,系统的内存很紧张了,好多新对象在着急的等着分配内存,不允许你再慢慢的并发回收内存,但这意味着停顿时间的大幅度增加)


5、G1发生了concurrent mode fail之后退化成了单线程回收整个堆




为什么老年代垃圾回收效率比新生代低很多?

为什么Yong GC比Old GC慢?为什么Minor gc速度比Major GC慢?

这里的Yong GC=Minor gc,Old GC=Major GC

Old GC的速度一般会比yong gc慢10倍以上


1、从并行和并发机制,并行和并发的默认线程数上,可以看出-XX:ConcGCThreads=(-XX:ParallelGCThreads + 3)/ 4

(XX:ParallelGCThreads是并行线程数,XX:ConcGCThreads是并发线程数)

(并行是STOP-THE-WORD,并发是回收垃圾的时候,应用查询继续在执行)

2、(时间换空间s1、s2)新生代复制算法比较快。Eden区回收时直接全部清空,存活的对象存放到内存容量比较小的s1,少了解决内存碎片整理  加上直接copy的速度,效率很高。


3、(新生代GC根据卡表,只需扫描部分老年代)卡表数据库结构,卡表为一个比特位的集合,卡表中每一位表示老年代4KB的空间,每一个比特位可以用来表示老年代的某一区域中的所有对象是否持有新生代对象的引用。
这样新生代GC时,可以不用花大量时间扫码所有老年代对象,来确定每一个对象的引用关系,
而可以先扫码卡表,只有卡表的标记位为1时,才需要扫码给定区域的老年代对象
而卡表位为0的锁住区域的老年代对象,一定不含有新生代对象的引用


4、(空间换时间),老年代标记清除算法会导致内存碎片化,因此就引入了标记整理算法,执行完毕后,存活的对象会按序放置,移动对象的内存地址(重点),来解决碎片化,但是执行时间较长。


5、老年代区内存容量一般较大,回收需要预留比较大的空间(老年代GC是并发执行,重新标记的时候修正引用关系),这样的话内存利用率就低(相对于新生代利用率eden+from=90%,新生代存活率低不需要预留太多内存)



这篇关于Full GC为什么那么慢?为什么老年代垃圾回收效率比新生代低很多?为什么Minor gc速度比Major GC慢?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/560434

相关文章

使用Python实现Windows系统垃圾清理

《使用Python实现Windows系统垃圾清理》Windows自带的磁盘清理工具功能有限,无法深度清理各类垃圾文件,所以本文为大家介绍了如何使用Python+PyQt5开发一个Windows系统垃圾... 目录一、开发背景与工具概述1.1 为什么需要专业清理工具1.2 工具设计理念二、工具核心功能解析2.

JVM垃圾回收机制之GC解读

《JVM垃圾回收机制之GC解读》:本文主要介绍JVM垃圾回收机制之GC,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、死亡对象的判断算法1.1 引用计数算法1.2 可达性分析算法二、垃圾回收算法2.1 标记-清除算法2.2 复制算法2.3 标记-整理算法2.4

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

Java下载文件中文文件名乱码的解决方案(文件名包含很多%)

《Java下载文件中文文件名乱码的解决方案(文件名包含很多%)》Java下载文件时,文件名中文乱码问题通常是由于编码不正确导致的,使用`URLEncoder.encode(filepath,UTF-8... 目录Java下载文件中文文件名乱码问题一般情况下,大家都是这样为了解决这个问题最终解决总结Java下

MySQL报错sql_mode=only_full_group_by的问题解决

《MySQL报错sql_mode=only_full_group_by的问题解决》本文主要介绍了MySQL报错sql_mode=only_full_group_by的问题解决,文中通过示例代码介绍的非... 目录报错信息DataGrip 报错还原Navicat 报错还原报错原因解决方案查看当前 sql mo

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

离心萃取机废旧磷酸铁锂电池回收工艺流程

在废旧磷酸铁锂电池的回收工艺流程中,离心萃取机主要应用于萃取除杂的步骤,以提高回收过程中有价金属(如锂)的纯度。以下是结合离心萃取机应用的废旧磷酸铁锂电池回收工艺流程: 电池拆解与预处理 拆解:将废旧磷酸铁锂电池进行拆解,分离出电池壳、正负极片、隔膜等部分。破碎与筛分:将正负极片进行破碎处理,并通过筛分将不同粒径的物料分开,以便后续处理。 浸出与溶解 浸出:采用适当的浸出工艺(如二段式逆

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。