JVM垃圾回收——对象进入老年代

news2025/1/11 0:26:29

目录

1、什么是大对象以及大对象对垃圾回收的影响        

2、什么情况下对象会进入老年代

2.1  当创建对象的大小超过-XX:PretenureSizeThreshold的设定值

2.2 长期存活的对象将进入老年代

2.3 动态年龄判定

2.4 空间担保分配

什么是空间分配担保?

为什么要进行空间担保?


1、什么是大对象以及大对象对垃圾回收的影响        

        大对象是指需要大量连续内存空间的Java对象,最典型的就是很长的字符串,或者很大的数组对象。在实际开发中我们要尽量避免大对象,因为在分配内存空间时,明明有很大的空间,但是连续的空间不足以创建大对象时,JVM不得不提前进行垃圾回收,以获取足够的空间来创建大对象;第二个原因,创建大对象在复制对象的时候需要高额的内存复制开销。

2、什么情况下对象会进入老年代

对象进入老年代这里不考虑ZGC(ZGC并没有设置分代)的情况。

2.1  当创建对象的大小超过-XX:PretenureSizeThreshold的设定值

        HotSpot虚拟机提供了-XX:PretenureSizeThreshold参数,指定大于该设置值的对象直接在老年代分配,这样做的目的是避免在Eden和两个Survivor区之间来回复制,产生大量的内存复制操作。

注:-XX:PretenureSizeThreshold参数只对Serial和ParNew新生代的收集器有效。

代码验证

package com.wssnail.test;

/**
 * @author 熟透的蜗牛
 * @version 1.0
 * @description: 测试超过PretenureSizeThreshold设定值直接进入老年代
 * 本代码在jdk8环境下运行 3145728=3*1024*1024
 * -Xms20M -Xmx20M -Xmn10M -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PreTenureSizeThreshold=3145728 -verbose:gc
 * -XX:+PrintCommandLineFlags
 * @date 2023/4/9 16:00
 */
public class TestPretenureSizeThreshold {

    private static final int _1Mb = 1024 * 1024;

    public static void main(String[] args) {
        byte[] allocation;
        allocation = new byte[4 * _1Mb];
    }
}
-Xms20M
-Xmx20M
-Xmn10M
-XX:+UseConcMarkSweepGC
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
-XX:PretenureSizeThreshold=3145728
-verbose:gc
-XX:+PrintCommandLineFlags

 从上图可以看出,4MB的对象直接分配到了老年代中,占用了4096KB,没有在新生代进行分配。

2.2 长期存活的对象将进入老年代

        这里长期存活的对象是指采用分代收集来管理内存,每经过一次Minor GC而没有进入老年代,当经历过MaxTenuringThreshold设定的阈值(默认是15)之后,会进入老年代。

        关注公众号熟透的蜗牛,领取面试资料

代码验证

package com.wssnail.test;

/**
 * @author 熟透的蜗牛
 * @version 1.0
 * @description: 测试超过PretenureSizeThreshold设定值直接进入老年代
 * 本代码在jdk8环境下运行
 * -Xms20M -Xmx20M -Xmn10M -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1 -verbose:gc  -XX:+PrintCommandLineFlags -XX:+PrintTenuringDistribution
 * @date 2023/4/9 16:00
 */
public class TestMaxTenuringThreshold {

    private static final int _1Mb = 1024 * 1024;

    public static void main(String[] args) {
        byte[] allocation1, allocation2, allocation3;
        allocation1 = new byte[_1Mb / 4]; //256kb 进入老年代跟MaxTenuringThreshold的值有关
        allocation2 = new byte[_1Mb * 4];
        allocation3 = new byte[_1Mb * 4];
        allocation3 = null;
        allocation3 = new byte[_1Mb * 4];
    }
}
MaxTenuringThreshold=1

 MaxTenuringThreshold=15

 MaxTenuringThreshold该参数取值0-15,由于对象头中只有4个二进制位来存储分代年龄,所以该值最大只能是15,超过该范围报错。

2.3 动态年龄判定

        HotSpot虚拟机并不是要求对象的年龄必须达到-XX:MaxTenuringThreshold设定的阈值才能晋升到老年代,如果在Survivor空间中低于或者等于某年龄的所有的对象的大小的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象就可以进入老年代,而无须等-XX:MaxTenuringThreshold设定的值。比如Survivor总大小为1M,而Survivor空间中超过5岁的对象的大小超过了0.5M,那么只要对象大于等于5岁就可以直接进入老年代。

关注公众号熟透的蜗牛,领取面试资料

2.4 空间担保分配

        JVM使用分代收集算法,将堆内存划分为年轻代和老年代,两块内存分别采用不同的垃圾回收算法,空间担保指的是老年代进行空间分配担保。

什么是空间分配担保?

  • 在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象的总空间。
  • 如果大于,则此次Minor GC是安全的
  • 如果小于,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果HandlePromotionFailure=true,那么会继续检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小,如果大于,则尝试进行一次Minor GC,但这次Minor GC依然是有风险的;如果小于或者HandlePromotionFailure=false,则改为进行一次Full GC。

为什么要进行空间担保?

        是因为新生代采用复制收集算法,假如大量对象在Minor GC后仍然存活(最极端情况为内存回收后新生代中所有对象均存活),而Survivor空间是比较小的,这时就需要老年代进行分配担保,把Survivor无法容纳的对象放到老年代。老年代要进行空间分配担保,前提是老年代得有足够空间来容纳这些对象,但一共有多少对象在内存回收后存活下来是不可预知的,因此只好取之前每次垃圾回收后晋升到老年代的对象大小的平均值作为参考。使用这个平均值与老年代剩余空间进行比较,来决定是否进行Full GC来让老年代腾出更多空间。但是假如某一次的MinorGC后存活的对象激增,超过了历史平均值,那么就有可能会导致担保失败,如果担保失败了,那么就不得不进行一次Full GC ,这样导致的结果就是停顿时间变长。

        关注公众号熟透的蜗牛,领取面试资料

        JDK 6 Update 24之后-XX:HandlePromotionFailure参数不会影响虚拟机的空间担保策略,更改之后的规则为只要老年代的连续空间大于新生代对象总大小或者大于历次晋升的平均大小,就会执行Minor GC。否则进行Full GC

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

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

相关文章

uploads靶场通关(1-11关)

Pass-01(JS校验) 看题目我们准备好我们的php脚本文件,命名为1.php 上传该php文件,发现上传失败 方法一:将浏览器的JavaScript禁用 然后就能上传了 方法二: 查看源码,发现只能上传以下形式的文…

【Docker】LXC所实现的隔离性、Linux Namespace等讲解

前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…

域名解析异常有哪些办法?如何实现动态域名解析?

什么是域名解析? 域名解析就是把域名解析成一个ip地址,我们大多数人都喜欢记忆域名,但是机器只认识IP地址,只要这个IP地址对应相关域名,这就叫域名解析。 工作中常会遇到域名解析故障,比如访问站点对应的…

FPGA问答系列--Vivado Schematic中的实线和虚线有什么区别?

FPGA问答系列–Vivado Schematic中的实线和虚线有什么区别? 前言:本文章为FPGA问答系列,我们会定期整理FPGA交流群(包括其他FPGA博主的群)里面有价值的问题,并汇总成文章,如果问题多的话就每周…

ChatPPT一键制作PPT,效果拉满!

💧 C h a t P P T 一键制作 P P T ,效果拉满! \color{#FF1493}{ChatPPT一键制作PPT,效果拉满!} ChatPPT一键制作PPT,效果拉满!💧 🌷 仰望天空,妳我…

阿里云nginx配置https踩坑(配置完后访问显示无法访问此网站)

本人小前端一枚,最近在玩服务器部署自己的东西时踩了个坑!!! server {listen 443 ssl;server_name localhost;ssl_certificate 证书.com.pem;ssl_certificate_key 证书.com.key;#后台管理静态资源存放location / { #文件目…

2023-06-04 Unity ScriptableObject2——ScriptableObject 的应用

文章目录 一、配置数据二、复用数据三、多态特性的利用四、单例模式获取数据 一、配置数据 ​ ScriptableObject 数据文件非常适合用来做配置文件: 配置文件的数据在游戏发布之前定规则配置文件的数据在游戏运行时只会读出来使用,不会改变内容在 Unity…

MPS|如何学习电路设计?帮你快速上手

​电路设计是电子工程中的重要领域之一,涉及到电子元件的选择、电路的设计和分析、电路板的制作等多个方面。对于初学者来说,学习电路设计需要掌握一定的基础知识和技能,同时需要有耐心和实践经验。本文将从七个方面总结如何学习电路设计&…

Vue (9)

Vue (9) 文章目录 1. 消息订阅与发布1.1 总结1.2 修改 TodoList 案例 2. 为 TodoList 添加编辑功能3. $nextTick4. 过度与动画4.1 动画效果4.2 过度效果4.3 集成第三方动画4.4 总结4.5 修改 TodoList 案例 1. 消息订阅与发布 上文我们已经将全局事件总线学完了知道了全局事件总…

day6 -- 数据的分组和描述性统计

学习内容 描述性统计函数,包括平均值,最大/小值,行数,总和使用 GROUP BY子句和HAVING子句 对数据进行分组操作 描述性统计数函数 除了上面提到的聚合函数外,MySQL还提供了以下其他一些常用的聚合函数: – …

Python学习40:维吉尼亚密码——解密

凯撒密码的加密强度是很低的,只需简单地统计字频就可以破译。人们在单一凯撒密码的基础上扩展出多表密码,称为“维吉尼亚”密码。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪…

【环境搭建】一些奇奇怪怪的环境问题

【设备信息】我的设备是4070ti,支持cuda12.0,但是目前用的还是11.7 1)fatal error: cusparse.h: No such file or directory 因为cuda版本和改名的原因,这个在cuda版本中比较有效的解决办法是: sudo apt search libcusparse得到…

基于SpringBoot+Vue的自习室预订系统设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

C/C++开发,opencv读写图像函数详解

目录 一、cv::imread函数读取图像 1.1 imread函数 1.2 imread函数的参数解析 1.3 imread函数实践案例 1.4 编译及测试 二、cv::imwrite函数存储图像 2.1 cv::imwrite函数 2.2 imwrite函数参数解析 2.3 imwrite函数实践案例 2.4 编译及测试 一、cv::imread函数读取图像 1.1 im…

Lecture 5 Part of Speech Tagging

目录 POS application: Information Extraction 词性应用:信息提取 POS Open Class 开放类词性Problem of word classes: Ambiguity 词类问题:模糊性Tagsets 标记集Penn Treebank Tags:Derived Tags: 衍生标签Tagged Text Example 标记文本示例Reasons f…

Java 字符串基本操作

一、Java 字符串比较 1、equals用法 String类覆盖了Object类的equals()方法,并提供了自己的实现,它根据它们的内容比较两个字符串的相等性。 equals() 方法用于将字符串与指定的对象比较。 语法 public boolean equals(Object anObject)参数 anObje…

Dockerfile常用指令及其含义

编写dockerfile文件中常用指令: 指令说明FROM指明当前的镜像基于哪个镜像构建:LABEL标记镜像信息,添加元数据ARG定义构建镜像过程中使用的变量ENV指定环境变量VOLUME创建一个数据卷挂载点USER指定运行容器时的用户名或 UIDWORKDIR配置工作目录EXPOSE容器…

chatgpt赋能python:Python区分:为什么选择python?

Python区分:为什么选择python? Python是一种高级语言,一种功能强大且易于学习的编程语言。 它可用于各种领域,包括科学计算,Web开发和数据分析等。 Python的简单性和灵活性使其成为许多行业和开发者的首选编程语言。 …

R语言 tidyverse系列学习笔记(持续更新)

tidyverse 译 “洁净的宇宙” > “极乐净土” 以 iris 鸢尾花数据集为例 ** 查看数据集** ** 查看维度dimention** dim(iris)iris 数据集有150个对象(observation),5列 ( Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Spe…

大疆无人机 MobileSDK(遥控器/手机端)开发 v5版<2>

前言 v5.x版本的功能与v4.x基本相同,都是获取飞机的姿态信息、获取无人机多媒体文件、操作多媒体文件、航线规划等。不过在上一章节中也大致说了一些两个版本的中API的差别,下面是根据一些API使用所完成的一些功能,因为项目原因只能提供部分代码供参考,后续如果有这方面需…