JVM学习日志(十一) 对象进入老年代的情况 及 空间担保机制

简介: 对象进入老年代的情况 及 空间担保机制 简述

对象进入老年代的情况

  1. 幸存者区装不下
  2. 对象太大了
  3. 年龄到达15岁

对象动态年龄判断

为了能能够更好的使用不同程序的内存状况,HotSpot虚拟机并不是永远要求对象的年龄必须达到-XX MaxTenuringThreshold才能够晋升为老年代,如果在Survivor空间中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代,无需等到-XX:MaxTenuringThreshold中要求的年龄

空间分配担保机制

老年代空间够用

首先:在发生MinorGC 之前,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那这一次MinorGC可以确保是安全的

试想一个极端情况就是MinOrGC后所有对象存活下来,那所有的对象都会进入老年代,如果老年代判断剩余空间是大于所有对象的,那么就可以放心担保进入老年代

老年代空间不够

如果执行MinOrGC 之前,发现老年代的可能用内存空间已经小于新生代的全部对象大小了,那么这个时候就有可能新生代minorGC后的对象全部存活,然后需要转移到老年代,但是老年代空间又不够的情况,(理论上有这种可能),因此JVM在MinorGC之前,当判断老年代的可用内存已经小于新生代的全部对象大小,会有一个参数-XX:HandlePromotionFailure是否设置,如果有该值的设置,那会继续检查老年代最大可用连续空间是否大于历次晋升到老年代对象的平均大小,当判断到历次平均大小是小于老年代可用内存空间的,将尝试进行一次MinorGC,尽管这次MinorGC是有风险的,如果小于,或者-XX:HandlePromotionFailure没有设置,那这是就要改为一次FullGC

老年代垃圾回收算法

标记整理算法

标记-复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低,更为关键的是,如果不想浪费50%空间,就需要有额外的空间进行分配担保,以应对被使用的内容中所有对象都是100%存活的极端情况,所以在老年代一般不能直接选用这种算法

针对老年代对象的存亡特征,1974年提出了另外一种有针对性的标记整理算法,其中的标记过程仍然与"标记-清除算法"一样,但是后续的步骤不是直接对可回收对象进行清理,而是让所有存货的对象都向内存空间的一端移动,然后直接清理掉边界以外的内存,"标记整理算法"的示意图

image-20230426105513748.png

标记-清除算法与标记整理算法本质差异在于前者是一种非移动式的回收算法,而后者是移动式的,是否移动回收后的存活对象是一项优缺点并存的风险决策:

如果移动存活对象,尤其是在老年代这种每次回收都有大量对象存活的区域,移动存活对象并更新,所有引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用程序才能进行,这就更加让使用者不得不小心翼翼的权衡其弊端了,像这样的停顿被最初的虚拟机设计者形象的描述为“stop The world"

老年代的垃圾回收算法速度至少比新生代的垃圾回收算法的的速度慢10倍!如果频繁的出现老年代的FullGC,会导致系统性能被严重影响,出现频繁卡顿的情况

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
存储 监控 Cloud Native
|
4月前
|
存储 Go
Go 浅析主流日志库:从设计层学习如何集成日志轮转与切割功能
本文将探讨几个热门的 go 日志库如 logrus、zap 和官网的 slog,我将分析这些库的的关键设计元素,探讨它们是如何支持日志轮转与切割功能的配置。
110 0
Go 浅析主流日志库:从设计层学习如何集成日志轮转与切割功能
|
2月前
|
存储 缓存 Java
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
39 1
|
2天前
|
SQL 监控 关系型数据库
【MySQL学习】MySQL的慢查询日志和错误日志
【MySQL学习】MySQL的慢查询日志和错误日志
|
5天前
|
前端开发 Java 开发者
JVM类加载器的分类以及双亲委派机制
JVM类加载器的分类以及双亲委派机制
|
6天前
|
存储 Java 物联网
SpringBoo利用 MDC 机制过滤出单次请求相关的日志
SpringBoo利用 MDC 机制过滤出单次请求相关的日志
|
8天前
|
监控 Docker 容器
Docker从入门到精通:Docker log 命令学习
了解 Docker 日志管理对容器监控至关重要。`docker logs` 命令用于查看和管理容器日志,例如,`docker logs <container_name>` 显示容器日志,`-f` 或 `--follow` 实时跟踪日志,`--tail` 显示指定行数,`--timestamps` 添加时间戳,`--since` 按日期筛选。Docker 支持多种日志驱动,如 `syslog`,可通过 `--log-driver` 配置。有效管理日志能提升应用程序的稳定性和可维护性。
13 0
|
15天前
|
监控 Java 关系型数据库
JVM工作原理与实战(十三):打破双亲委派机制-线程上下文类加载器
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了打破双亲委派机制的方法、线程上下文类加载器等内容。
15 2
|
15天前
|
监控 安全 前端开发
JVM工作原理与实战(十二):打破双亲委派机制-自定义类加载器
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了打破双亲委派机制的方法、自定义类加载器等内容。
17 1
|
15天前
|
监控 前端开发 安全
JVM工作原理与实战(十一):双亲委派机制
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了双亲委派机制、父类加载器、双亲委派机制的主要作用、双亲委派机制常见问题等内容。
14 1