JVM基础(9)——新生代调优

这篇具有很好参考价值的文章主要介绍了JVM基础(9)——新生代调优。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

一、简介

本章和下一章,我们将通过一个实际案例讲解如何进行JVM参数调优:合理优化新生代、老年代、Eden和Survivor各个区域的内存大小,接着再尽量优化参数避免新生代的对象进入老年代,尽量让对象留在新生代里被回收掉。

本章先针对新生代调优进行讲解,后续章节,我们会针对老年代调优再专门讲解,新生代调优的整个过程都围绕以下几点来思考:

  • 每秒占用多少内存?
  • 多长时间触发一次Minor GC?
  • 每次Minor GC后,存活对象的平均大小是多少?
  • Survivor能否容纳存活对象?
  • 会不会因为Survivor无法容纳频繁进入老年代?
  • 会不会因为动态年龄判断规则进入老年代?

我们先来看下案例的背景。

1.1 案例背景

假设生产环境有一个每日上亿访问量的电商系统,日平均订单量50万。在双11等大促场景下,峰值为每秒1000笔订单。现在部署3台4核8G的机器,每台每秒抗300笔订单请求。

我们的目标就是对JVM有限的内存资源进行合理的分配和优化,让JVM的Minor GC次数尽量少,同时尽量避免Full GC。

1.2 内存使用模型估算

交代完了背景,我们再来估算下高峰时期的JVM内存使用模型:

一笔订单一般20个左右的字段,按1kb算,那1秒钟300笔订单就是300kb,然后还需要算上其它业务对象(比如库存、积分、商户等等),所以放大20倍。此外,订单系统还有其它操作,特别是查询操作,同样耗费内存,所以再放大10倍,那么每秒钟的内存总开销就是:
$$
300kb2010=60MB
$$

我们假设1s过后,这60MB的对象都会失去引用变成垃圾。

JVM基础(9)——新生代调优,jvm专题,jvm

二、JVM内存分配

2.1 初始情况

4核8G的机器,一般分配4G给JVM。假设最初状态下,Java堆内存分配3G(新生代1.5G,老年代1.5G),每个线程的栈空间1MB,一个JVM大概几百个线程,所以总共给虚拟机栈几百兆,然后再给永久代256MB:

-Xms3072M -Xmx3072M -Xmn1536M -Xss1M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:SurvivorRatio=8

参数-XX:SurvivorRatio采用默认值8,即Eden和Survivor按照默认的8:1:1分配内存。

空间担保机制的JVM参数-XX:HandlePromotionFailure在JDK1.6以后就被废弃了,JDK1.6以后只需要判断“老年代可用空间 > 新生代对象总和”或“老年代可用空间 > 历次Minor GC晋升到老年代的对象平均大小”,这两个条件满足任意一个,就可以直接进行Minor GC,不会提前触发Full GC。

JVM基础(9)——新生代调优,jvm专题,jvm

2.2 优化Survivor空间

系统运行期间,每秒都会在新生代产生60MB对象,然后1秒后就失去引用,大约25左右,新生代中Eden区的1.2G空间就会被占满:

JVM基础(9)——新生代调优,jvm专题,jvm

此时,就会触发是否进行Minor GC的判断,由于老年代可用空间(1.5G) > 历次Minor GC晋升到老年代的对象平均大小(0G),所以Minor GC直接运行,一下子回收99%的新生代中的垃圾,除了最近1秒的还在处理,剩下的都处理完了,总共余留大约100MB存活对象,存放对象放入S1区,然后清空Eden:

JVM基础(9)——新生代调优,jvm专题,jvm

然后,再运行20秒后,Eden区再次被占满,再次触发并执行Minor GC,存放对象放入S2,同时清空Eden和S1:

JVM基础(9)——新生代调优,jvm专题,jvm

按照上面的测算,每次存活对象的平均大小为100MB,Survivor区的大小为150MB,非常接近,很可能出现某次Minor GC后存活对象超过了150MB,导致Survivor区无法容纳,使得存活对象晋升到老年代。

此外,每次存活对象的年龄是相同的,根据动态年龄规则,100MB超过了Survivor的50%,所以很可能这100MB存放对象会直接晋升到老年代。

所以,Survivor区只分配150MB空间是不够的。所以可以考虑 把新生代调整为2G,老年代调整为1G,这样每个Survivor就有200MB空间 :

JVM基础(9)——新生代调优,jvm专题,jvm

此时,JVM参数如下:

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:SurvivorRatio=8

对于任何系统,应尽量让每次Minor GC后的对象都留在Survivor中,不要进入老年代,所以Survivor区是首要优化点。

2.3 是否优化晋升年龄

默认情况,新生代存活对象的年龄到达15后,就会进入老年代,那么我们是否要通过参数-XX:MaxTenuringThreshold来调整年龄的上限值,以避免对象进行老年代呢?

答案是否定的,一般来说,经历了15次Minor GC还存在于新生代的,都是那些需要长期存活的核心业务对象,比如@Service、@Controller等注解的对象。对于这些对象,它们就应该进入老年代,况且这类对象的数量不会很多,一般一个系统也就是几十MB而已。

所以,反而可以降级晋升年龄,我们这里设置成5,即-XX:MaxTenuringThreshold=5。

2.4 是否优化大对象

大对象是可以直接进入老年代的,一般来说-XX:PretenureSizeThreshold这个阈值设置成1MB足以,因为很少有超过1MB的大对象。如果有,可能是你提前分配了一个大数组或集合之类的对象,用以存放缓存。

2.5 指定垃圾回收器

最后,还要指定垃圾回收器,新生代用ParNew,老年代用CMS,最终,JVM的参数设置如下:

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -XX:PretenureSizeThreshold=1M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC

ParNew垃圾收集器的核心参数,其实就是配套的新生代内存大小,Eden和Survivor的比例,只要你设置合理,避免存活对象放不下Survivor而进入老年代,或者是动态年龄判断后进入老年代,那么Minor GC一般不会有什么问题。

三、总结

本章通过一个电商示例,分析了JVM新生代的参数优化,核心优化目的就是尽量让每次存活的对象都进入Survivor,避免进入老年代。

本章主要针对新生代进行优化,下一章我们将结合案例分析老年代的垃圾回收和JVM参数优化。文章来源地址https://www.toymoban.com/news/detail-794881.html

到了这里,关于JVM基础(9)——新生代调优的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 可达性分析、三色标记、新生代、老年代的关系是什么

            jvm提供了垃圾回收器进行垃圾回收,垃圾回收器的职责就是回收内存中不再被引用的对象,以便释放内存。垃圾回收器利用可达性分析算法去分析哪些对象需要被回收,可达性分析算法是这样的:首先一些对象被定义为gc roots,然后沿着这些gc roots对象的引用链往下查

    2024年02月14日
    浏览(37)
  • 探讨AI绘画:技术进步与伦理道德并存的新生代艺术?

      随着人工智能技术的不断发展,AI绘画也成为了热门领域之一。在这个领域中,Midjourney是一款受到广泛关注的AI绘图工具。但是,随着AI绘画技术的发展,也有越来越多的问题和争议浮现出来。在这里,我们将从几个角度来探讨AI绘画的发展现状以及可能带来的影响。   

    2024年02月11日
    浏览(41)
  • JVM-JVM调优基础(理论)

    申明:文章内容是本人学习极客时间课程所写,作为笔记进行记录,文字和图片基本来源于课程资料,在某些地方会插入一点自己的理解,未用于商业用途,侵删。 原资料地址:课程资料 JVM参数 标准参数 定义:稳定的参数不会随着Java版本的变化而变化。通常以 短横线开头

    2024年02月19日
    浏览(36)
  • JVM基础(12)——G1调优

    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖,挖的越深,基础越扎实! 阶段1、深入多线程 阶段2、深入多线程设计模式 阶段3、深入juc源码解析

    2024年01月22日
    浏览(45)
  • 3.Java面试题—JVM基础、内存管理、垃圾回收、JVM 调优

    一篇文章掌握整个JVM,JVM超详细解析!!! JVM (Java虚拟机) 是运行 Java 字节码 的 虚拟机 。 JVM 针对 不同系统 有 特定实现 ( Windows 、 Linux 等),目的是 同样的代码 在 不同平台 能运行出 相同的结果 。 Java 语言 要经过 编译 和 解释 两个步骤: 编译 :通过 编译器 将 代码 一

    2024年02月15日
    浏览(49)
  • JVM基础(10)——老年代调优

    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖,挖的越深,基础越扎实! 阶段1、深入多线程 阶段2、深入多线程设计模式 阶段3、深入juc源码解析

    2024年01月20日
    浏览(37)
  • JVM 17 调优指南:如何进行JVM调优,JVM调优参数

    在这篇文章中,我会详细介绍JVM调优的概念、重要性和具体的JVM调优参数。此外,我将提供12个实用的代码示例,每个示例都会包含JVM调优参数和相应的Java代码。 本文已收录于,我的技术网站 ddkk.com,有大厂完整面经,工作技术,架构师成长之路,等经验分享 JVM调优是调整

    2024年02月02日
    浏览(45)
  • JVM 8 调优指南:如何进行JVM调优,JVM调优参数

    这篇文章将详细介绍如何进行JVM 8调优,包括JVM 8调优参数及其应用。此外,我将提供12个实用的代码示例,每个示例都会结合JVM启动参数和Java代码。 本文已收录于,我的技术网站 ddkk.com,有大厂完整面经,工作技术,架构师成长之路,等经验分享 JVM调优是指通过调整Java虚拟

    2024年01月21日
    浏览(55)
  • JVM 11 调优指南:如何进行JVM调优,JVM调优参数

    JVM 11的优化指南:如何进行JVM调优,以及JVM调优参数有哪些”这篇文章将包含JVM 11调优的核心概念、重要性、调优参数,并提供12个实用的代码示例,每个示例都会结合JVM调优参数和Java代码 本文已收录于,我的技术网站 ddkk.com,有大厂完整面经,工作技术,架构师成长之路,

    2024年01月16日
    浏览(54)
  • JVM 21 的调优指南:如何进行JVM调优,JVM调优参数

    聊聊关于JVM 21的优化指南。这篇文章将会深入探讨如何进行JVM调优,介绍一些关键的JVM调优参数,并提供12个实用的代码示例。由于篇幅较长,我会分几个部分来详细讲解,之前写的也有33篇系列教程JVM调优实战打击也可以去围观。 JVM(Java虚拟机)调优是一个复杂但重要的任

    2024年01月24日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包