一个JVM参数,服务超时率降了四分之三
先说结论:通过优化Xms,改为和Xmx一致,使系统的超时率降了四分之三

1. 背景
一个同事说他负责的服务在一次上线之后超时率增加了一倍

2. 分析
2.1 机器的监控
首先找了一台机器,看了监控

上线后最明显的变化就是CPU使用率变高了
2.2 上线改动点
上线只加了简单的判断条件,按理不应该导致CPU变高成这样
2.3 CPU使用率随时间变低
又发现了一个奇怪的现象是,在没有上线的情况下,CPU使用率突然降低了,然后就一直保持着很低的状态

CPU降低之后,超时率也有所降低,现在大概能理解超时是和CPU使用率有关的,可能存在CPU瓶颈
2.4 依赖的服务
既然在没有上线的情况下,CPU使用率会降低,肯定有什么因素影响,猜测可能是依赖的服务,但依赖的服务太多,也没办法一个一个去看,哪个调用有问题
2.5 CPU和上线的关系
于是还是想在CPU使用率上找找问题,因为是上线导致的CPU使用率变高,所以看了其他上线时间的CPU使用率
还是有点思路了,发现大部分上线之后CPU使用率是会变高,部分没有(后面知道,因为有的上线本身就是优化,所以CPU使用率也会变低)
2.6 CPU和内存的关系
之前一直在关心CPU,突然看见了内存的使用率,一下就明白的问题所在,从下面这张图可以看出,CPU使用率和内存使用率是成反比的

使用Java的都应该清楚,内存不够的时候,就会STW,然后去启动GC线程去GC,而且一般情况GC线程数和CPU核数是一致的,这个服务也是如此,此时CPU使用率必然是会变高的
上面3月6号CPU突然下降的原因也是因为内存使用变高了,这是在没有上线的情况下

2.7 内存和JVM参数
可以看到上面的图中,CPU使用率高的时候,内存占用只有20%左右,为什么空这这么多内存不用呢?看下JVM参数
-Xmx16g -Xms4g -Xss1024K -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=10 -XX:MetaspaceSize=512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=8 -XX:G1HeapRegionSize=16m -XX:-OmitStackTraceInFastThrow
Xms配的是4G,也就是说JVM在启动时只会申请4G内存,当内存不足时,先会GC,当GC释放的内存还不够时,才会去申请更大的内存
这样的策略一般是为了节省内存,但目前主流的都是容器,节省下来的内存也不会给别的服务利用,所以我们这可以直接把Xms改为16G
改完之后立即得到了很好的效果,超时率降了四分之三,不过后续因为内存使用率变高,超过了阈值,所以又把Xmx和Xms调整为14G,这个问题可以参考我之前的文章一次Java服务内存过高的分析过程
3. 总结
- Xms配置过小,JVM启动时内存不足导致GC线程占用过多CPU
- CPU不足时,超时率增加,CPU充足时,超时率降低
- Xms配置和Xmx一样,超时率降低
4. Xms和Xmx
这两个参数使用Java的都比较了解
Xmx: JVM的最大堆内存
Xms: JVM的初始堆内存
4.2 不一致的坏处
- 堆内存不够时更频繁的触发GC
- 当GC完之后内存也不够时,向系统申请内存,会花费更多的时间
4.2 改为一致的好处
为了避免在生产环境由于heap内存扩大或缩小导致应用停顿,降低延迟,同时避免每次垃圾回收完成后JVM重新分配内存。所以,-Xmx和-Xms一般都是设置相等的
在生产环境中把Xms和Xmx设为相同值也是Oracle官方推荐
5. 感想
这个配置从机器上线跑了两年一直如此,大部分时间性能没被充分利用,现在有二十台机器都是以这样一种低性能模式跑了这么久,这绝对是一种浪费
在第三篇参考文章中,有个人的评论正好和我相反,他认为一开始将Xms和Xmx设置为一样,而实际没用那么多,其实也是一种浪费,不过这是18年前的文章,那时容器没有兴起,服务都在一个物理机上面共享内存,会是有这种问题的
在容器中,节省的内存别的服务也利用不了,所以Xms最后设置和Xmx一致,但是容器也是可能造成浪费的,比如上面我把Xmx和Xms从16G改为14G,从监控上来看耗时和超时率下降了一点,也就是把这个容器的内存往下调一点也是可以接受的,具体调到多少合适也不太确定
不过这种优化很没有必要,内存是很便宜的,而且适量冗余一些性能也可以理解
既然这么多好处,为什么Oracle不默认把Xms和Xmx设置为一致呢,我觉得可能是目前还是有大部分Java应用都不是容器环境,全局考虑,没有这样做,或许后续Java会判断是否是容器环境来自动设置Xms
参考
[2] Is there any advantage in setting Xms and Xmx to the same value?
[3] large difference between -Xms and -Xmx values in jvm
一个JVM参数,服务超时率降了四分之三的更多相关文章
- JVM参数MetaspaceSize的误解
前言 昨天谢照东大神在群里提出一个问题:怎么查看Metaspace里具体包含的是什么,起因是他的某个服务设置了-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=5 ...
- JVM参数调优总结
一.前言 要想成为一名高级Java开发具备JVM调优的能力必不可少,能够根据项目实际情况进行JVM调优的前提是理解JVM原理和常用JVM参数的含义及作用,虽然<深入理解Java虚拟机>这本 ...
- 一个性能较好的JVM参数配置
一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...
- 一个性能较好的JVM参数配置(转)
一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...
- jvm参数优化
一.HotSpot JVM 提供了三类参数 现在的JVM运行Java程序(和其它的兼容性语言)时在高效性和稳定性方面做的非常出色.例如:自适应内存管理.垃圾收集.及时编译.动态类加载.锁优化等.虽然有 ...
- 关键业务系统的JVM参数推荐(2018仲夏版) (强烈推荐 唯品会)
年更贴,因为两年里遇到的事情,一些想法变了.也补充了不少VJTools的内容,比如为伸手党们准备的jvm-options.sh. 在关键的业务系统里,除了继续追求技术人员最爱的高吞吐与低延时之外,系统 ...
- 关键系统的JVM参数推荐
1. 性能篇 1.1 建议的性能参数 1. 取消偏向锁: -XX:-UseBiasedLocking JDK1.6开始默认打开的偏向锁,会尝试把锁赋给第一个访问它的线程,取消同步块上的synchron ...
- jvm参数解析(含调优过程)
前阵 对底层账单系统进行了压测调优,调优的最后一步--jvm启动参数中,减小了线程的堆栈空间:-XX:ThreadStackSize=256K,缩减至原来的四分之一,效果明显,不过并没有调 ...
- JVM参数配置 java内存区域
java内存区域 一些基本概念 http://www.importnew.com/18694.html https://www.cnblogs.com/wangyayun/p/6557851.html ...
- Tomcat 调优及 JVM 参数优化
Tomcat 本身与 JVM 优化 Tomcat:调整Server.xml JVM:bat启动服务方式的话修改catalina.bat 服务式启动的话参考:http://www.cnblogs.com ...
随机推荐
- 【人脸识别】OpenCV获取自己的图像
思路:先获取10000张自己的图像,然后通过CNN神经网络进行学习. 第一步:先获取自己的脸的数据.如何做? 代码如下: import cv2 import os import sys import ...
- 07. C语言程序执行流程控制
[有条件执行语句] if esle 语句 if else 语句根据一个条件确定是否执行一段代码,执行条件是一个布尔值,布尔值为true则执行,为false则不执行,同时可以设置不符合条件时执行的语句. ...
- Triton 源码初步研读
一.核心接口形态 def jit( fn: Optional[T] = None, *, version=None, do_not_specialize: Optional[Iterable[int] ...
- 怎么样给Oracle数据库中的表添加列?
首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...
- Cesium的HeadingPitchRange 用法
这个有别于headingpitchroll, headingpitchroll是用在orientation属性上的(比如相机的setView,flyTo,以及entities.add中) Headin ...
- cesium基础知识汇总PPT版
以上教程来自火星科技,原视频教程地址如下: https://ke.qq.com/course/468292/3985600802137412#term_id=100560563
- installshield 安装jdk并配置环境变量
今天来通过installshield安装jdk以及配置环境变量,本质上是调用第三方安装程序. 首先将jdk的安装文件添加到我们的安装程序中 然后编写我们的脚本 选择BEHAVIOR AND LOGIC ...
- Linux系统中如何查看磁盘情况
Linux不像windows系统那样方便的图形界面,特别是作为服务器使用的时候,只有命令行可以使用. 我有个云服务器平时用来做一些数据分享用的,最近想看看磁盘和其中文件的占用情况,于是搜索并学习了一些 ...
- Android 13 - Media框架(8)- MediaExtractor
关注公众号免费阅读全文,进入音视频开发技术分享群! 上一篇我们了解了 GenericSource 需要依赖 IMediaExtractor 完成 demux 工作,这一篇我们就来学习 android ...
- 一个 .NET 开源的地图组件库 - Mapsui
前言 今天大姚给大家分享一个.NET开源(MIT License).免费.同时支持多平台框架(MAUI.WPF.Avalonia.Uno.Blazor.WinUI.Eto..NET Android 和 ...