jvm - GC篇

news2025/2/2 23:18:20

如何减慢一个对象进入老年代的速度,如何降低GC的次数

堆内存细分

年轻代(Young Generation):

新创建的对象首先被分配在年轻代中。年轻代又被进一步划分为一个Eden区和两个Survivor区(通常称为S0和S1)。
当Eden区满时,会触发一次Minor GC(垃圾回收),存活的对象会被移动到一个Survivor区,不存活的对象会被清理。

老年代(Old Generation 或 Tenured Generation)

  • 经过多次GC后仍存活的对象会被移动到老年代。老年代的空间通常比年轻代大,因为它存储的是生命周期较长的对象。
  • 老年代的垃圾回收频率通常低于年轻代,但每次GC耗时更长,因为涉及到更多的对象和更大的内存区域。

永久代(Permanent Generation)或元空间(Metaspace)

  • 在早期版本的JVM中,永久代用于存储JVM内部结构,如类的元数据、方法的字节码等。从Java 8开始,永久代被元空间替代。
  • 元空间不在堆内存中,而是直接使用本地内存(即操作系统的内存),主要用于存储类的元数据。

大对象区(Large Object Space,或称为Huge Object Space)

  • 一些JVM实现可能会为大对象提供专门的内存区域。这些对象由于大小超过了某个阈值,直接在老年代或特定的大对象区进行分配,以避免在年轻代中频繁复制。

空间大小

Eden与Survivor空间的比例可能接近8:1,也就是说,当每个Survivor空间占用10%的新生代空间时,Eden空间占用80%的新生代空间。新生代的总大小通常是堆内存的1/3到1/4,但这也取决于具体的JVM配置和可用内存。Survivor空间虽然有两个区域,但总有一个区域是空,也不会对其计算大小

老年代通常占据堆内存的其余部分。如果新生代占用了堆的1/3,那么老年代则大约占用2/3。

元空间并不在堆内存中,而是使用本地内存(native memory),用于存储类元数据。
在JDK 8及之后的版本中,默认情况下,元空间是没有硬性限制的(即没有默认的最大值),它会根据需要扩展,直到受限于系统内存。

垃圾收集的流程

常规情况

  • 对象最初分配在Eden区。随着应用程序的运行,Eden区会逐渐填满。当我们Eden区满了后,就会触发GC操作,一般被称为 YGC / Minor GC操作,将伊甸园区中的不再被其他对象所引用的对象进行销毁。再加载新的对象放到伊甸园区。
  • 存活的对象会被移动到一个幸存者from区
  • 随着应用程序的运行,Eden区会再次填满,执行Minor GC操作,将伊甸园区中的不再被其他对象所引用的对象进行销毁,伊甸园区依然存活的对象存放到幸存者to区,同时幸存者from区的对象也复制到幸存者to区,经过一次回收后还存在的对象,将其年龄加 1。如此循环往复,当Survivor中的对象的年龄达到15的时候,将会触发一次 Promotion 晋升的操作,也就是将年轻代中的对象晋升到老年代中,在对伊甸园区做GC的时候,幸存者区满了,幸存对象会被直接提升到老年代(Old Generation)。这意味着即使对象的年龄没有达到通常提升的阈值,它们也会被移动到老年代,因为没有足够的空间在幸存者区容纳它们
  • 如果老年代也没有足够的空间来容纳这些被提升的对象,JVM可能会触发一个完整的垃圾收集(Full GC),这是一个更彻底的收集过程,涉及整个堆,包括年轻代和老年代。Full GC通常比仅针对年轻代的Minor GC要慢得多,因为它需要检查和清理整个堆空间。
  • 内存不足错误(OutOfMemoryError):如果老年代也已满,并且无法为对象提供更多空间,JVM将无法继续运行,并抛出java.lang.OutOfMemoryError。这通常是一个严重的错误,表明应用程序需要更多内存,或者有内存泄漏需要修复

存在大对象的情况

对象过大,Eden园区放不下了,此时要先对Eden园区做一下垃圾回收,如果还是放不下,说明这是一个大对象,可以直接往老年代去放,老年代还是放不下,进行FULL GC,还是放不下,报OOM,重复过程:这个过程会随着Eden区的再次填满而重复,Survivor From区和Survivor To区会在每次Minor GC后交换角色。

from/to区,翻转的目的/好处是什么?

  • 内存回收:垃圾收集的主要任务是识别并回收不再使用的对象所占用的内存。通过翻转,可以清空整个伊甸园区(Eden Space)和一个幸存者区(“From”),这样能快速回收大量内存。
  • 减少碎片:通过将存活对象复制到一个连续的内存区域("To"区),可以避免内存碎片的产生。这样,存活对象在内存中保持紧凑排列,而不是散布在内存的各个角落。
  • 方便计数:在这个过程中,对象的年龄也被跟踪。每次对象在幸存者区之间移动时,它们的年龄就会增加

命令

-Xms:设置堆空间大小初始内存大小(年轻代 + 老年代),默认是服务器可用物理内存的1/64,但服务器可用物理内存比物理内存值要小,因为操作系统自身会占用一部分内存。所以想要一个精确值需要手动去指定,比如-Xms600m,最终实际值大约是575,因为俺默认大小来算,幸存者区占1/24,始终有一个是空的
-Xmx:设置堆空间大小最大内存大小(年轻代 + 老年代),默认是服务器物理内存的1/4
-XX:Survivor:设置幸存者区在新生代的比例,默认是8
-XX:NewRatio:设置新生代和老年代的比例,默认是2,即新生代占总内存的1/3
-XX:printGCDetail

jinfo -flag NewRatio

public static void main(string[] args){
	//返回Java虚拟机中的堆内存总量
	long initialMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024;
	//返回Java虚拟机试图使用的最大堆内存量
	long maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024;
	System.out.println("-Xms : " + initialMemory + "M");
	System.out.println("-Xmx : " + maxMemory + "M");
}

开发环境设置,建议堆空间大小初始内存大小和堆空间大小最大内存大小相等,避免频繁的扩容与释放

堆的细分

开发中,不同的对象生命周期不同,有的对象转瞬即逝,有的对象甚至伴随整个jvm的运行周期

  • 转瞬即逝,比如局部变量,方法执行完毕对应的引用出栈,后续会被回收
  • 生命周期非常长的对象,比如静态变量,集合,例如我们比较熟悉的Spring使用一级缓存来存储单实例类型的bean,这个一级缓存本质上也是一个静态的map,此外还有各种池类资源比如线程池,链接池,他们的生命周期都很长,往往伴随整个jvm的运行周期

生命周期非常长的对象,没有必要对他们持续的做GC,所以当一个对象年龄超过15的时候,jvm认为这是一个稳定的对象,晋升老年代,老年代的GC频率是比较低的

伊甸园区

-XX:Survivor:设置幸存者区在新生代的比例,默认是8,但有一个自适应机制,所以需要显示声明这个值为8,才能获得正确的比例

-XX maxTenuringThreshold:

-Xmn:设置新生代大小

超过了80%对象都是朝生夕死的

几户所有对象都是在伊甸园区创建的,除非是

如何使对象更快的从新生代晋升老年代

在JVM的垃圾回收机制中,对象的晋升主要是通过两种方式实现的:

通过设置对象的年龄阈值。当对象在新生代中经历了一定次数的垃圾回收后,就会被晋升到老年代中。这个次数可以通过-XX:MaxTenuringThreshold参数设置。默认情况下,这个值是15。如果你想让对象更快的晋升到老年代,你可以降低这个值。

通过设置新生代的大小。如果新生代的空间不足以容纳所有的存活对象时,那么还没有达到年龄阈值的对象也会被晋升到老年代。因此,你也可以通过减小新生代的大小来加速对象的晋升。这个可以通过-XX:NewSize参数设置。

以上两种方式都可以使对象更快的从新生代晋升到老年代,但是也需要注意,过快的晋升可能会导致老年代的空间占用增加,从而影响到垃圾回收的效率。所以,在设置这些参数时,需要根据实际的应用情况进行权衡。

可达性分析算法

可达性分析算法的基本思路是通过一系列的称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到"GC Roots"没有任何引用链相连时,则证明此对象是不可用的,可作为GC Roots引用链的对象

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象。
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象。
  • 方法区中常量引用的对象。
  • 方法区中类静态属性引用的对象。
  • 被同步锁synchronized持有的对象

被堆中某个实例所引用的对象会被垃圾回收吗
如果只是被堆中某个实例锁引用,那要看这个引用它的实例对象是否由GC ROOT的起始点可达,如果不可达,如果说明这只是实例对象之间的引用,那么这些实例对象在下次GC中都是会被作为垃圾被回收的

栈中的引用被回收,它所引用的对象会被垃圾回收吗
要看情况,当这个实例对象栈中的引用被回收时,要看下这个对象是否还能GC ROOT的起始点可达,比如局部变量,栈中的引用被回收时,那就是不可达,下次GC被垃圾回收,如果是静态变量,栈中的引用被回收时,这个对象依然还能通过GC ROOT的起始点可达

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2项目(一)

项目介绍 电商前台项目 技术架构:vuewebpackvuexvue-routeraxiosless.. 封装通用组件登录注册token购物车支付项目性能优化 一、项目初始化 使用vue create projrct_vue2在命令行窗口创建项目 1.1、脚手架目录介绍 ├── node_modules:放置项目的依赖 ├──…

[LeetCode]day9 203.移除链表元素

203. 移除链表元素 - 力扣(LeetCode) 题目描述 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入:head [1,2,6,3,4,5,6], v…

TOF技术原理和静噪对策

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时,也能帮助其他需要参考的朋友。如有谬误,欢迎大家进行指正。 一、什么是TOF TOF 是Time of Flight的缩写,它是一种通过利用照射波和反射波之间的时间差来测量到物体的距离的测…

B-树:解锁大数据存储和与快速存储的密码

在我们学习数据结构的过程中,我们会学习到二叉搜索树、二叉平衡树、红黑树。 这些无一例外,是以一个二叉树展开的,那么对于我们寻找其中存在树中的数据,这个也是一个不错的方法。 但是,如若是遇到了非常大的数据容量…

园区智能化系统实现管理与服务的智能化转型与创新进阶

内容概要 园区智能化系统的出现,标志着管理与服务向智能化转型的重要一步。这一系统不仅仅是一个技术解决方案,更是一个全面提升园区运营效率与安全性的独特工具。通过集成大数据分析、物联网和人工智能,园区智能化系统能够为各类园区如工业…

LabVIEW无人机航线控制系统

介绍了一种无人机航线控制系统,该系统利用LabVIEW软件与MPU6050九轴传感器相结合,实现无人机飞行高度、速度、俯仰角和滚动角的实时监控。系统通过虚拟仪器技术,有效实现了数据的采集、处理及回放,极大提高了无人机航线的控制精度…

AtCoder Beginner Contest 391(ABCDE)

A - Lucky Direction 翻译: 给你一个字符串 D,代表八个方向(北、东、西、南、东北、西北、东南、西南)之一。方向与其代表字符串之间的对应关系如下。 北: N东: E西: W南: S东…

MINIRAG: TOWARDS EXTREMELY SIMPLE RETRIEVAL-AUGMENTED GENERATION论文翻译

感谢阅读 注意不含评估以后的翻译原论文地址标题以及摘要介绍部分MiniRAG 框架2.1 HETEROGENEOUS GRAPH INDEXING WITH SMALL LANGUAGE MODELS2.2 LIGHTWEIGHT GRAPH-BASED KNOWLEDGE RETRIEVAL2.2.1 QUERY SEMANTIC MAPPING2.2.2 TOPOLOGY-ENHANCED GRAPH RETRIEVAL 注意不含评…

HTB:LinkVortex[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用gobuster对靶机进行路径FUZZ 使用ffuf堆靶机…

3D图形学与可视化大屏:什么是材质属性,有什么作用?

一、颜色属性 漫反射颜色 漫反射颜色决定了物体表面对入射光进行漫反射后的颜色。当光线照射到物体表面时,一部分光被均匀地向各个方向散射,形成漫反射。漫反射颜色的选择会直接影响物体在光照下的外观。例如,一个红色的漫反射颜色会使物体在…

什么是门控循环单元?

一、概念 门控循环单元(Gated Recurrent Unit,GRU)是一种改进的循环神经网络(RNN),由Cho等人在2014年提出。GRU是LSTM的简化版本,通过减少门的数量和简化结构,保留了LSTM的长时间依赖…

基于微信小程序的酒店管理系统设计与实现(源码+数据库+文档)

酒店管理小程序目录 目录 基于微信小程序的酒店管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员模块的实现 (1) 用户信息管理 (2) 酒店管理员管理 (3) 房间信息管理 2、小程序序会员模块的实现 (1)系统首页 &#xff…

Java-数据结构-优先级队列(堆)

一、优先级队列 ① 什么是优先级队列? 在此之前,我们已经学习过了"队列"的相关知识,我们知道"队列"是一种"先进先出"的数据结构,我们还学习过"栈",是"后进先出"的…

爬虫基础(四)线程 和 进程 及相关知识点

目录 一、线程和进程 (1)进程 (2)线程 (3)区别 二、串行、并发、并行 (1)串行 (2)并行 (3)并发 三、爬虫中的线程和进程 &am…

C语言初阶力扣刷题——349. 两个数组的交集【难度:简单】

1. 题目描述 力扣在线OJ题目 给定两个数组,编写一个函数来计算它们的交集。 示例: 输入:nums1 [1,2,2,1], nums2 [2,2] 输出:[2] 输入:nums1 [4,9,5], nums2 [9,4,9,8,4] 输出:[9,4] 2. 思路 直接暴力…

Sqoop导入MySQL中含有回车换行符的数据

个人博客地址:Sqoop导入MySQL中含有回车换行符的数据 MySQL中的数据如下图: 检查HDFS上的目标文件内容可以看出,回车换行符位置的数据被截断了,导致数据列错位。 Sqoop提供了配置参数,在导入时丢弃掉数据的分隔符&…

LightM-UNet(2024 CVPR)

论文标题LightM-UNet: Mamba Assists in Lightweight UNet for Medical Image Segmentation论文作者Weibin Liao, Yinghao Zhu, Xinyuan Wang, Chengwei Pan, Yasha Wang and Liantao Ma发表日期2024年01月01日GB引用> Weibin Liao, Yinghao Zhu, Xinyuan Wang, et al. Ligh…

stm32硬件实现与w25qxx通信

使用的型号为stm32f103c8t6与w25q64。 STM32CubeMX配置与引脚衔接 根据stm32f103c8t6引脚手册,采用B12-B15四个引脚与W25Q64连接,实现SPI通信。 W25Q64SCK(CLK)PB13MOSI(DI)PB15MISO(DO)PB14CS&#xff08…

FPGA 使用 CLOCK_DEDICATED_ROUTE 约束

使用 CLOCK_DEDICATED_ROUTE 约束 CLOCK_DEDICATED_ROUTE 约束通常在从一个时钟区域中的时钟缓存驱动到另一个时钟区域中的 MMCM 或 PLL 时使 用。默认情况下, CLOCK_DEDICATED_ROUTE 约束设置为 TRUE ,并且缓存 /MMCM 或 PLL 对必须布局在相同…

一个开源 GenBI AI 本地代理(确保本地数据安全),使数据驱动型团队能够与其数据进行互动,生成文本到 SQL、图表、电子表格、报告和 BI

一、GenBI AI 代理介绍(文末提供下载) github地址:https://github.com/Canner/WrenAI 本文信息图片均来源于github作者主页 在 Wren AI,我们的使命是通过生成式商业智能 (GenBI) 使组织能够无缝访问数据&…