《JVM由浅入深学习【六】 2024-01-10》JVM由简入深学习提升分享

2024-01-10 13:12

本文主要是介绍《JVM由浅入深学习【六】 2024-01-10》JVM由简入深学习提升分享,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

    • 1.jvm堆内存分代模型
    • 介绍一下JVM中堆的垃圾回收过程
      • 堆的结构
      • 新生代的垃圾回收流程
        • 1. Minor GC
        • 2. Full GC
        • 总结
      • 什么是老年代空间分配担保机制
      • 什么情况下对象会进入老年代?
      • JVM 运行时数据区 元空间的特点及作用?
      • 结语:

1.jvm堆内存分代模型

在这里插入图片描述

介绍一下JVM中堆的垃圾回收过程

当Java应用程序运行时,它在堆内存中分为新生代(Young Generation)、老年代(Old Generation)和持久代(Permanent Generation,Java 8之后被元数据区替代)等几个区域。新生代主要用于存放新创建的对象,而垃圾回收主要集中在新生代进行。

堆的结构

  1. 新生代(Young Generation):包括三个区域,Eden空间和两个Survivor空间(通常命名为S0和S1)。对象首先在Eden空间分配,经过一轮Minor GC 后如果仍然存活,则会被移到Survivor空间,经过多次(minor15次,cms收集器默认6次)后会晋升到老年代。当然可以自己设置次数,下面是官方文档
    **注意:**即使对象的年龄尚未达到设定的阈值,如果Survivor区中的空间占用超过50%,这些对象也可能被提前晋升到老年代。这是因为为了避免Survivor区溢出,JVM可能会进行提前晋升。
    结论–>动态年龄判断: Survivor 区的对象年龄从小到大进行累加,当累加到 X 年龄 (某个年龄)时占用空间的总和大于50% (可以使用-XX:TargetSurvivorRatio=? 来设置保留多少空闲空间,默认值是 50) ,那么比 X 年龄大的对象都会晋升到老年代 在这里插入图片描述3. 这两个可以查看垃圾回收器默认值在这里插入图片描述

  2. 老年代(Old Generation):用于存放生命周期较长的对象,经过多次Minor GC(15次的s区域来回回收,这里次数也称为年龄,即15岁进入到老年代)或者经过一次Full GC后的对象会晋升到这个区域。

  3. 持久代(Permanent Generation):在Java 7及之前,主要用于存放类的元数据信息,包括类的结构、方法等。在Java 8及之后,被元数据区替代。

新生代的垃圾回收流程

新生代的垃圾回收主要分为两个阶段:Minor GC和Full GC。

1. Minor GC
  • 触发条件: 当Eden空间满时触发Minor GC。

  • 回收过程:

    • 首先,垃圾回收器标记并清理Eden空间中不再被引用的对象。
    • 存活的对象会被移到Survivor空间,如果Survivor空间满,将会晋升到老年代。
    • 清理后,Eden空间变为新的工作区域,等待下一次的对象分配。
  • 特点:

    • Minor GC的速度较快,因为它只需要清理新生代,而且很多对象在新生代很快被回收。
2. Full GC
  • 触发条件: 在老年代空间不足时触发Full GC。或者是由于Minor GC过程中晋升到老年代的平均大小大于老年代的剩余空间时。

  • 回收过程:

    • Full GC会对整个堆进行清理,包括新生代和老年代。
    • 它会停止应用程序的所有线程,进行垃圾回收,因此 Full GC 的耗时较长。
    • 对象的引用关系被重新整理,不再被引用的对象所回收。
  • 特点:

    • Full GC对整个堆进行回收,包括新生代和老年代,速度较慢。
总结

新生代的垃圾回收主要通过Minor GC来清理Eden空间和Survivor空间,快速回收短时间内创建的对象。而Full GC则是针对整个堆内存进行的,较为耗时。这种分代垃圾回收的策略有效提高了垃圾回收的效率,延长了老年代的垃圾回收触发时间,提高了整体的应用程序性能。

什么是老年代空间分配担保机制

  1. 老年代空间分配担保机制是Java虚拟机为了避免由于新生代Minor GC导致的空间不足而触发一次Full GC,从而提高垃圾回收效率的一种机制。具体而言,它保证了在发生Minor GC时,虚拟机在老年代预留一定的内存空间,以应对新生代对象晋升到老年代的情况。

  2. 这个机制的设计基于这样一个考虑:在一次Minor GC之前,虚拟机会首先检查老年代的剩余空间是否大于新生代所有对象的总空间,如果是,那么Minor GC可以放心进行。如果不足以容纳新生代所有对象,那么虚拟机会查看老年代中的存活对象是否能够在某个特定的年龄阈值之下就能被全部安置到老年代,如果这个条件成立,同样触发Minor GC,否则,进行一次Full GC。

  3. 这个担保机制的核心思想是为了尽量避免因为新生代对象晋升导致的Full GC。因为Minor GC的频率通常比Full GC低得多,而且Minor GC的速度更快,因此通过老年代空间分配担保机制,可以在大多数情况下避免因为新生代GC而触发Full GC,提高了垃圾回收的效率。
    在这里插入图片描述

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

躲过 15 次 GC之后进入老年代,可通过JVM 参数“-XX:MaxTenuringThreshold”来设 置年龄,默认为 15 岁
2、动态对象年龄判断
3、老年代空间担保机制
4、大对象直接进入老年代

  • 大对象是指需要大量连续内存空间的 Java 对象,比如很长的字符串或者是很大的数组或者List 集合,大对象在分配空间时,容易导致内存明明还有不少空间时就提前触发垃圾回收以获得足够的连续空间来存放它们,而当复制对象时,大对象又会引起高额的内存复制开销,为了避免新生代里出现那些大对象,然后屡次躲过 GC 而进行来回复制,此时JVM 就直接把该大对象放入老年代,而不会经过新生代;
  • 我们可以通过JVM 参数“-XX:PretenureSizeThreshold”设置多大的对象直接进入老年代,该值为字节数,比如“1048576”字节就是 1MB,该参数表示如果创建一个大于这个大小的对象,比如一个超大的数组或者 List 集合,此时就直接把该大对象放入老年代,而不会经过新生代-XX:PretenureSizeThreshold 参数只对 Serial 和 ParNew 两款新生代收集器有效,其他新生代垃圾收售器不支持该参数,如果必须使用此参数讲行调优,可考虑 ParNew+CMS 的收集器组合。

JVM 运行时数据区 元空间的特点及作用?

  • 1、在JDK1.8 开始才出现元空间的概念,之前叫方法区/永久代
  • 2、元空间与 Java 堆类似,是线程共享的内存区域
  • 3、存储被加载的类信息、常量、静态变量、常量池、即时编译后的代码等数据
  • 4、元空间采用的是本地内存,本地内存有多少剩余空间,它就能扩展到多大空间,也可以设置元空间大小;
    -XX:MetaspaceSize=20M -XX:MaxMetaspaceSize=20m
  • 5、元空间很少有 GC 垃圾收集,一般该区域回收条件苛刻,能回收的信息比较少,所以 GC很少来回收

结语:

在Java中,垃圾回收是一项重要的技术,通过自动管理内存资源,使得开发者可以更专注于业务逻辑的实现而不用过多关心内存的分配和释放。通过深入理解垃圾回收机制,我们可以更好地优化代码,提高程序性能,确保系统的稳定性和可维护性。

感谢您的阅读,希望本文对您理解和应用Java中的垃圾回收机制有所帮助。如果有任何疑问或建议,欢迎留言交流,共同学习进步。谢谢!

这篇关于《JVM由浅入深学习【六】 2024-01-10》JVM由简入深学习提升分享的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/590923

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis