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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 对象进入老年代的情况 及 空间担保机制 简述

对象进入老年代的情况

  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日志并进行多维度分析。
目录
相关文章
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
60 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
1月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
31 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
15天前
|
存储 监控 Java
JVM进阶调优系列(8)如何手把手,逐行教她看懂GC日志?| IT男的专属浪漫
本文介绍了如何通过JVM参数打印GC日志,并通过示例代码展示了频繁YGC和FGC的场景。文章首先讲解了常见的GC日志参数,如`-XX:+PrintGCDetails`、`-XX:+PrintGCDateStamps`等,然后通过具体的JVM参数和代码示例,模拟了不同内存分配情况下的GC行为。最后,详细解析了GC日志的内容,帮助读者理解GC的执行过程和GC处理机制。
|
1月前
|
Java 应用服务中间件 程序员
JVM知识体系学习八:OOM的案例(承接上篇博文,可以作为面试中的案例)
这篇文章通过多个案例深入探讨了Java虚拟机(JVM)中的内存溢出问题,涵盖了堆内存、方法区、直接内存和栈内存溢出的原因、诊断方法和解决方案,并讨论了不同JDK版本垃圾回收器的变化。
29 4
|
1月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
43 3
|
1月前
|
SQL 缓存 Java
JVM知识体系学习三:class文件初始化过程、硬件层数据一致性(硬件层)、缓存行、指令乱序执行问题、如何保证不乱序(volatile等)
这篇文章详细介绍了JVM中类文件的初始化过程、硬件层面的数据一致性问题、缓存行和伪共享、指令乱序执行问题,以及如何通过`volatile`关键字和`synchronized`关键字来保证数据的有序性和可见性。
28 3
|
1月前
|
缓存 前端开发 Java
JVM知识体系学习二:ClassLoader 类加载器、类加载器层次、类过载过程之双亲委派机制、类加载范围、自定义类加载器、编译器、懒加载模式、打破双亲委派机制
这篇文章详细介绍了JVM中ClassLoader的工作原理,包括类加载器的层次结构、双亲委派机制、类加载过程、自定义类加载器的实现,以及如何打破双亲委派机制来实现热部署等功能。
42 3
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
11天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
117 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
1月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
216 3