JVM系统优化实践(8):订单系统的垃圾回收案例

news2024/9/23 15:21:12

您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~


上回说到了年轻代和老年代的两个垃圾回收器:ParNew和CMS,并且将CMS的GC过程也一并介绍了,现在来看个订单系统的案例。

假设有这样的订单系统:

1、每日亿级流量,500万DAU,每日50万单集中在4小时高峰期;

2、大促(如双11)期间,就可能产生1000单/秒的峰值;

3、假设需增加3台机器,平均300单/台,4C8G。

案例目标:优化JVM,尽量避免Full GC。

按500单/秒的请求来估算的话,也就是:

500 * 1K * 20倍(单个开销) * 10倍(相关对象) = 100M

即每秒会产生100M(垃圾)。

按此消费水平,内存模型是:

1、4C8G内存,JVM内存 = 物理内存 / 2 = 4G内存;

2、JVM堆分配3G(年轻代1.5G,老年代1.5G);

3、JVM栈每线程分配1M;

4、剩余内存再配置其他JVM参数

所以常规的JVM参数配置就是这样的:

-Xms3072M -Xmx3072M -Xmn1536M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M

但按此配置,年轻代15秒后就会被填满。

所以稍稍调整下,增加-XX:SurvivorRatio参数:

-Xms3072M -Xmx3072M -Xmn1536M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8

-XX:SurvivorRatio=8,导致Eden只有1.2G,会提前触发Minor GC:

接下来可以再考虑优化Survivor。它的问题是:

1、会经常出现Survivor空间不足而直接进入老年代;

2、超过Survivor空间50%规则(会直接进入老年代)。

建议:

1、调整年轻代和老年代空间大小;

2、因为普通业务系统的大部分对象生成周期都很短,根本不应该频繁进入老年代;

3、尽量让对象留在年轻代里。

因此,对于任何系统,首要考虑的就是尽量让对象都留在Survivor里。调整后的JVM配置:

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8

同时,可以降低进入老年代的“年龄”大小,给Survivor腾空间。调整后的JVM配置:

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5

另一方面,为了不让过大的对象进入老年代,可以考虑对进入老年代的对象大小进行调整,当有超过指定大小的内存对象时,就直接进入老年代。调整后的JVM配置:

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -XX:PretenureSizeThreshold=1M

之前说过默认超过Survivor空间大小的50%时,存活对象就会进入老年代,因此这里也可以优化。调整后的JVM配置:

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -XX:PretenureSizeThreshold=1M -XX:TargetSurvivorRatio=50

最后别忘了指定GC,年轻代用ParNew,老年代用CMS。调整后的JVM配置:

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -XX:PretenureSizeThreshold=1M -XX:TargetSurvivorRatio=50 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC

那么各位可以根据这个思路,估算一下自己公司的生产系统,合理设置并优化JVM参数。

总结一下:

1、对象进入老年代的一般规律:

  • -XX:MaxTenuringThreshold=N,该参数值让年轻代对象躲过N次GC之后进入老年代。这些对象一般是@Entity、@Component、@Service、@Controller等注解标注出来的系统组件;

  • -XX:PretenureSizeThreshold=1M,年轻代中超过该值的对象就进入老年代;

  • -XX:TargetSurvivorRatio=50,Minor GC后存活对象的总大小如果超过该值就进老年代。

2、什么时候会触发Full GC?

  • -XX:HandlePromotionFailure,该参数没打开时触发Full GC(JDK1.6后已废弃);

  • 老年代可用空间<历次Minor GC后进入老年代的对象的平均大小时触发Full GC;

  • 老年代可用空间<要进入的老年代的存活对象大小时触发Full GC;

  • -XX:+UseCMSCompactAtFullCollection和XX:CMSInitiatingOccupancyFraction=92,老年代可用空间超过该值时触发Full GC,这两个必须配对出现(JDK1.8已不建议使用)。

大促期间,真正的系统压力峰值时间是有限的,比如持续2小时。如果JVM能做到500单/秒,大约1小时才触发一次Full GC,那么峰值过后,JVM的压力就会小很多,就不会触发Full GC了。

3、老年代GC时发生Concurrent Mode Failure的问题。

  • 当老年代使用空间超过92%时进行CMS,可用空间不足100M;

  • 有一批存活对象要进入老年代,大小200M;

  • 此时就发生Concurrent Mode Failure;

  • 但这种概率极小,不需要为极小概率事件调整JVM参数设置;

  • 也没有必要修改执行多少次Full GC之后进行碎片清理,因为经过优化后, Full GC执行次数大大降低了。

那么订单系统的最终配置是:


感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~

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

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

相关文章

常见数据结构

一. 数据结构概述、栈、队列 1. 数据结构概述 2. 栈数据结构的执行特点 3. 常见数据结构之队列 二. 常见数据结构之数组 数组它就是内存中的一块儿连续区域。数组变量存的是数组在堆内存当中的起始地址。数组查询任意索引位置的值耗时相同,数组根据索引查询速度快。…

Matlab中旧版modem.qammod与新版不兼容

最近,因为课题需要,在研究通信。在网上下了一个2015年左右的代码,其中用的是matlab旧版中的modem.qammod函数,但是旧版中的函数已经被删除了,(这里必须得吐槽一下,直接该函数内部运行机制就行呀…

Lasso回归理论及代码实现

Lasso回归的模型可以写作与一般线性回归相比, Lasso回归加入了回归项系数的一范数, 这样做是为了防止线性回归过程发生的过拟合现象. 直观点看, 其将的分量限制在了一个以圆点为中心以为边的正方形内. 与岭回归相比, 该模型得到的系数矩阵更为稀疏. 由于函数在0点不可导, 因而L…

第二章Linux操作语法1

文章目录vi和vim常用的三种模式vi和vim快捷键Linux开机,重启用户管理用户信息查询管理who和whoami用户组信息查询管理用户和组的相关文件实用指令集合运行级别帮助指令manhelp文件管理类pwd命令ls命令cd命令mkdir命令rmdir命令rm命令touch命令cp指令mv指令文件查看类…

Pytorch学习笔记#2: 搭建神经网络训练MNIST手写数字数据集

学习自https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html 导入并预处理数据集 pytorch中数据导入和预处理主要用torch.utils.data.DataLoader 和 torch.utils.data.Dataset Dataset 存储样本及其相应的标签,DataLoader在数据上生成一个可迭…

刷题小抄4-数组

在Python中数组的功能由列表来实现,本文主要介绍一些力扣上关于数组的题目解法 寻找数组中重复的数字 题目链接 题目大意: 给出一个数组,数组长度为n,数组里的数字在[0,n-1]范围以内,数字可以重复,寻找出数组中任意一个重复的数字,返回结果 解法一 该题最基础的思路是使用字…

[java Spring JdbcTemplate配合mysql实现数据批量删除

之前的文章 java Spring JdbcTemplate配合mysql实现数据批量添加和文章java Spring JdbcTemplate配合mysql实现数据批量修改 先后讲解了 mysql数据库的批量添加和批量删除操作 会了这两个操作之后 批量删除就不要太简单 我们看到数据库 这里 我们用的是mysql工具 这里 我们有…

Java——单词接龙

题目链接 leetcode在线oj题——单词接龙 题目描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk&#xff1a; 每一对相邻的单词只差一个字母。 对于 1 < i < k 时&#xff…

QML Text详解

1.简介 文本项可以显示普通文本和富文本。 2.示例 示例1&#xff1a;一个简单的text&#xff0c;可以设置字体颜色、大小等。 Window {visible: truewidth: 400height: 400title: qsTr("Hello World")Rectangle{width: 200height: 200border.width: 2Text {text: …

(flutter)黑苹果系统 Xcode iOS flutter 跑通真机模拟器 此oc clover 彼oc swift

前段时间写了关于flutter的一系列基础知识和入门的一些坑&#xff0c;中间把ios端的项目编译部署等工作一带而过&#xff0c;这里我觉得还是有必要专门写一篇文章来讲讲这个&#xff0c;顺便把环境问题也一起说了。 我们都知道开发ios应用需要用到苹果电脑&#xff0c;即使flu…

【NLP】Word2Vec 介绍

Word2Vec 是一种非常流行的自然语言处理技术&#xff0c;它将每个单词表示为高维向量&#xff0c;并且通过向量之间的相似度来表示单词之间的语义关系。 1 One-Hot 编码&#x1f342; 在自然语言处理任务中&#xff0c;我们需要将文本转换为计算机可以理解的形式&#xff0c;即…

ChatGPT后劲很大,问题也是

ChatGPT亮相即封神&#xff0c;最初的访客是程序员、工程师、AI从业者、投资人&#xff0c;最后是无数懵懂又好奇的普通人&#xff1a;ChatGPT是什么&#xff1f;自己会被ChatGPT取代吗&#xff1f;看待ChatGPT的立场也是两个极端&#xff1a; 快乐&#xff0c;是因为ChatGPT太…

科普| 什么是云原生?

“新冠疫情从根本上改变了商业模式&#xff0c;工作流向在线迁移的速度比以往任何时候都要快。越来越多的公司和消费者依靠电子商务“ B2B”和B2C”&#xff0c;以及网上银行促进创新以满足日益增长的客户需求&#xff0c;云原生技术在其中发挥重要作用&#xff0c;同时也加速了…

vm centos7搭建k8s集群

关闭防火墙&#xff0c;三台systemctl stop firewalld关闭selinux&#xff0c;三台sed -i s/enforcing/disabled/ /etc/selinux/config关闭swap&#xff0c;三台swapoff -a设置主机名&#xff0c;三台hostnamectl set-hostname 主机名&#xff0c;三个主机名分别设置成k8s-mast…

JavaScript新手学习手册-基础代码(一)

什么是JavaScript&#xff1f; 百度百科 什么是控制台&#xff1f; 网页➡快捷键F12 进入Console就是控制台&#xff0c;它的作用与开发软件相同&#xff0c;可以进行代码的编写在紫色位置进行编写&#xff0c;另外console.log()方法所打印的内容都是在此进行输出。 一&#…

Spark Join

Spark Join关联形式内关联外关联左外关联右外关联全外关联左半/逆关联关联机制NLJSMJHJ分发模式Join 选择等值 Join不等值 JoinJoin 按照关联形式&#xff08;Join Types&#xff09;划分 : 内关联、外关联、左关联、右关联 Join 按实现机制划分 : NLJ (Nested Loop Join) 、S…

【操作系统原理实验】页面替换策略模拟实现

选择一种高级语言如C/C等&#xff0c;编写一个页面替换算法的模拟实现程序。1) 设计内存管理相关数据结构&#xff1b;2) 随机生成一个页面请求序列&#xff1b;3) 设置内存管理模拟的关键参数&#xff1b;4) 实现该页面置换算法&#xff1b;5) 模拟实现给定配置请求序列的换页…

【python socket】实现websocket服务端

一、获取握手信息首先通过如下代码&#xff0c;我们使用socket来获取客户端的握手信息import socketsock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(("127.0.0.1", 8002)) sock.li…

启动项管理工具Autoruns使用实验(20)

实验目的 &#xff08;1&#xff09;了解注册表的相关知识&#xff1b; &#xff08;2&#xff09;了解程序在开机过程中的自启动&#xff1b; &#xff08;3&#xff09;掌握Autoruns在注册表和启动项方面的功能&#xff1b;预备知识 注册表是windows操作系统中的一个核心数据…

Android Framework-Android启动过程

第一个系统进程&#xff08;init&#xff09; Android设备的启动必须经历3个阶段&#xff0c;即Boot Loader、Linux Kernel和Android系统服务&#xff0c;默认情况下它们都有各自的启动界面。严格来说&#xff0c;Android系统实际上是运行于Linux内核之上的一系列“服务进程”…