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

news2024/11/16 21:43:41

作者简介:大家好,我是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内存分配

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。

2.2 优化Survivor空间

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

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

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

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

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

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

此时,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参数优化。

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

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

相关文章

【linux基础I/O(二)】文件系统讲解以及文件缓冲区的概念

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:Linux从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学更多操作系统知识   🔝🔝 基础I/O 1. 前言2. 理解C语言…

基于STM32的温室大棚环境检测及自动浇灌系统设计

需要全部资料请私信我! 基于STM32的温室大棚环境检测及自动浇灌系统设计 一、绪论1.1 研究背景及意义1.2 研究内容1.3 功能设计 二、系统方案设计2.1 总体方案设计 三、系统硬件设计3.1 STM32单片机最小系统3.2 环境温度检测电路设计3.3 土壤湿度检测电路设计3.4 光…

MySQL的事务机制

一、事务机制简述 事务机制,避免写入直接操作数据文件;利用日志来实现间接写入,与事务有关的, redo日志与undo日志;sql语句操作记录复制到undo日志然后增删改查操作的结果会记录在redo日志,如果操作没有什么问题就把数据同步到数…

Linux 抓包还不会?这篇文章赶紧收藏!

前言 什么是TCPDUMP TCPdump,全称dump the traffic on a network,是一个运行在linux平台可以根据使用者需求对网络上传输的数据包进行捕获的抓包工具。 tcpdump可以支持的功能: 1、在Linux平台将网络中传输的数据包全部捕获过来进行分析 …

k8s-调度 13

调度器通过 kubernetes 的 watch 机制来发现集群中新创建且尚未被调度到 Node 上的 Pod。调度器会将发现的每一个未调度的 Pod 调度到一个合适的 Node 上来运行。 kube-scheduler 是 Kubernetes 集群的默认调度器,并且是集群控制面的一部分。 如果你真的希望或者有…

分享一款刚开源的音乐人声分离工具!无需联网!页面化操作!

前言 人声分离 是一项重要的音频处理技术,它可以将混合音频中的 人声和背景音乐 分离出来,为音频处理和后期制作提供了便利。 随着人声分离技术的发展,越来越多的开源工具被开发出来,为音频处理领域带来了新的发展机遇。小编之前…

C# 图解教程 第5版 —— 第21章 异步编程

文章目录 21.1 什么是 异步21.2 async/await 特性的结构21.3 什么是异步方法21.3.1 异步方法的控制流21.3.2 取消一个异步操作21.3.3 在调用方法中同步地等待任务21.3.4 在异步方法中异步地等待任务21.3.5 Task.Delay 方法 21.4 GUI 程序中的异步操作(*)…

倒L天线设计

λ/4单极子天线具有工作带宽较宽,辐射效率较高的优点,但是其体积较大,随着无线终端设备的体积越来越小,对天线空间的要求也越来越严格,于是为了适应终端设备的发展,单极子天线开始出现一些变形,…

基于Python实现身份证信息识别

目录 前言身份证信息识别的背景与意义自动识别身份证的需求 实现环境与工具准备Python编程语言OpenCV图像处理库Tesseract OCR引擎 身份证信息识别算法原理图像预处理步骤(图像裁剪、灰度化 、二值化、去噪)信息提取与解析 Python代码实现通过OCR提取身份证号码代码解析身份证信…

SQL-修改数据

🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:重拾MySQL 🍹文章作者技术和水平很有限,如果文中出现错误&am…

计算机毕业设计 | SSM 校园线上订餐系统(附源码)

1, 概述 1.1 项目背景 传统的外卖方式就是打电话预定,然而,在这种方式中,顾客往往通过餐厅散发的传单来获取餐厅的相关信息,通过电话来传达自己的订单信息,餐厅方面通过电话接受订单后,一般通…

【博士每天一篇论文-综述】Brain Inspired Computing : A Systematic Survey and Future Trends

阅读时间:2023-11-17 1 介绍 年份:2023 作者:李国琪 期刊:TechRxiv 引用量:2 这篇论文主要介绍了脑启发计算(Brain Inspired Computing,BIC)以及其在人工智能(Artifici…

MySQL安装服务启动失败解决方案

在安装MySQL中,应用配置阶段,显示服务启动失败 查看日志说服务启动失败 我的电脑是win764位 新装的操作系统,之前出现过权限不足的提示,首先定位故障为权限问题。由于MySQL80服务在 计算机管理->服务 里面显示户别为&#xff…

ubuntu20固定串口名称

查看串口的详细信息 udevadm info --name/dev/ttyUSB0结果: P: /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0 N: ttyUSB0 L: 0 S: serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UAR…

机器人持续学习基准LIBERO系列4——robosuite最基本demo

0.前置 机器人持续学习基准LIBERO系列1——基本介绍与安装测试机器人持续学习基准LIBERO系列2——路径与基准基本信息机器人持续学习基准LIBERO系列3——相机画面可视化及单步移动更新 1.robosuite的相关资料 是基于MuJoCo的机器人学习方针环境,提供一套基准环境…

2024.1.8 Day04_SparkCore_homeWork

目录 1. 简述Spark持久化中缓存和checkpoint检查点的区别 2 . 如何使用缓存和检查点? 3 . 代码题 浏览器Nginx案例 先进行数据清洗,做后续需求用 1、需求一:点击最多的前10个网站域名 2、需求二:用户最喜欢点击的页面排序TOP10 3、需求三&#x…

2024年最好用的简历编辑工具,助你腾飞职业生涯!

随着科技的不断发展,求职竞争也愈发激烈。在2024年,如何在众多求职者中脱颖而出成为关键问题。为了帮助大家在职业生涯中取得更好的机会,特别推荐一款在2024年最为出色的简历编辑工具——芊芊简历。 1. 创新的编辑功能 芊芊简历拥有直观易用…

Matlab 使用 DH table 建立的 robot 和实际不符

机器人仿真 想借助 matlab robotics toolbox 来仿真机器人,但是直接输入自己的 DH table 显示出来的 robot 和实际不情况不符。 DH table 建立 robot Build Manipulator Robot Using Kinematic DH Parameters 主要使用 setFixedTransform,DH table 中…

YOLOV7剪枝流程

YOLOV7剪枝流程 1、训练 1)划分数据集进行训练前的准备,按正常的划分流程即可 2)修改train.py文件 第一次处在参数列表里添加剪枝的参数,正常训练时设置为False,剪枝后微调时设置为True parser.add_argument(--pr…

POI:对Excel的基本写操作 整理1

首先导入相关依赖 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><!--xls(03)--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version></depend…