JVM 性能调优 及 为什么要减少 Full GC
本文为博主原创,未经允许不得转载:
系统上线压测,需要了解系统的瓶颈以及吞吐量,并根据压测数据进行对应的优化。
对压测进行 JVM 性能优化,有两条思路:
第一种情况 : 使用压测工具 jmeter 进行小量并发业务测试, 通过 top 命令查看cpu是否会急速飙升。若在 小并发量压测时或单独调试时,出现 cpu 性能飙升,
那就需要对对应的业务接口进行代码分析,分析消耗cpu 的原因。
第二种情况:使用压测工具jmeter ,jvisulam 等进行大并发量业务测试,并使用 top 命令实时监控 cpu ,以及内存的使用情况,查看 垃圾回收
MinorGC 和 Full GC 的频率和情况。根据 GC 的数据进行对应的JVM参数设置,提高系统的可用性。
如何进行第一种情况调优:
1. CPU 迅速飙升,在业务服务器上进行监控,
1.通过 top 命令定位到占用 CPU 和内存 最高的线程
2. 并将对应的线程转为16进制,通过jstack 查询该线程的堆栈信息,从而定位到对应的代码,并进行代码分析
3. 进行代码性能优化
第二种情况调优:
第二种情况调优属于 JVM 参数性能调优,主要通过设置 堆(新生代和老年代)的大小以及GC 垃圾回收器,从而提高服务的性能。
该调优需要在压测时,需要对该 java 进程实时的垃圾回收情况进行监控。分析在压测业务吞吐量相对稳定时,GC的回收情况。
1. 使用 jstat 命令对指定的java 进程进行实时监控。并计算出一些关键数据。并给自己的系统设置一些初始性的JVM 参数:
比如 堆内存大小,年轻代大小,Eden和Survivor的比例,老年代的大小,大对象的阈值,大龄对象进入老年代的阈值等。
2. 查看年轻代对象的增长速率:
可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象,
如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。注意,一般系统可能有高峰期和日常期,所以需要在不
3. Young GC的触发频率和每次耗时
5. Full GC的触发频率和每次耗时
6. 优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。
尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。
在调试JVM 的堆大小时,可以根据JVM 堆得内存模型图进行推算参数值:

为什么要减少 Full GC:
通过设置JVM 的参数,减少Full GC 触发的频率,因为 Full GC 会导致 STW :top一the一World,简称STW,指的是Gc事件发生过程中,
会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应,有点像卡死的感觉,这个停顿称为STW。
为什么要减少 Full GC ,因为 Young GC 每次扫描的对象少,且对象的生命周期较短,容器GC ,而 Full GC 不仅需要扫描清理老年代的
垃圾对象,还需要清理 metaspace和新生代的垃圾对象,由于老年代中所保存的对象是生命周期较长的对象,不易清理,比较耗时,这就会
导致 STW 时间变长,服务不可用或卡顿的现象也就越长。
常用的 JVM 参数配置:
| 参数 | 说明 | 实例 |
|---|---|---|
| -Xms | 初始堆大小,默认物理内存的1/64 | -Xms512M |
| -Xmx | 最大堆大小,默认物理内存的1/4 | -Xms2G |
| -Xmn | 新生代内存大小,官方推荐为整个堆的3/8 | -Xmn512M |
| -Xss | 线程堆栈大小,jdk1.5及之后默认1M,之前默认256k | -Xss512k |
| -XX:NewRatio=n | 设置新生代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4 | -XX:NewRatio=3 |
| -XX:SurvivorRatio=n | 年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:8,表示Eden:Survivor=8:1:1,一个Survivor区占整个年轻代的1/8 | -XX:SurvivorRatio=8 |
| -XX:PermSize=n | 永久代初始值,默认为物理内存的1/64 | -XX:PermSize=128M |
| -XX:MaxPermSize=n | 永久代最大值,默认为物理内存的1/4 | -XX:MaxPermSize=256M |
| -verbose:class | 在控制台打印类加载信息 | |
| -verbose:gc | 在控制台打印垃圾回收日志 | |
| -XX:+PrintGC | 打印GC日志,内容简单 | |
| -XX:+PrintGCDetails | 打印GC日志,内容详细 | |
| -XX:+PrintGCDateStamps | 在GC日志中添加时间戳 | |
| -Xloggc:filename | 指定gc日志路径 | -Xloggc:/data/jvm/gc.log |
| -XX:+UseSerialGC | 年轻代设置串行收集器Serial | |
| -XX:+UseParallelGC | 年轻代设置并行收集器Parallel Scavenge | |
| -XX:ParallelGCThreads=n | 设置Parallel Scavenge收集时使用的CPU数。并行收集线程数。 | -XX:ParallelGCThreads=4 |
| -XX:MaxGCPauseMillis=n | 设置Parallel Scavenge回收的最大时间(毫秒) | -XX:MaxGCPauseMillis=100 |
| -XX:GCTimeRatio=n | 设置Parallel Scavenge垃圾回收时间占程序运行时间的百分比。公式为1/(1+n) | -XX:GCTimeRatio=19 |
| -XX:+UseParallelOldGC | 设置老年代为并行收集器ParallelOld收集器 | |
| -XX:+UseConcMarkSweepGC | 设置老年代并发收集器CMS | |
| -XX:+CMSIncrementalMode | 设置CMS收集器为增量模式,适用于单CPU情况。 |
JVM 性能调优 及 为什么要减少 Full GC的更多相关文章
- Java性能优化权威指南-读书笔记(二)-JVM性能调优-概述
概述:JVM性能调优没有一个非常固定的设置,比如堆大小设置多少,老年代设置多少.而是要根据实际的应用程序的系统需求,实际的活跃内存等确定.正文: JVM调优工作流程 整个调优过程是不断重复的一个迭代, ...
- JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码
本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍) ...
- jvm 性能调优
[转载]:http://blog.csdn.net/chen77716/article/details/5695893 最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一记录. 一 ...
- (转)JVM性能调优之生成堆的dump文件
转自:http://blog.csdn.net/lifuxiangcaohui/article/details/37992725 最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一 ...
- eclipse JVM 性能调优
最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一记录. 一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老 ...
- 如何合理的规划一次jvm性能调优
https://blog.csdn.net/miracle_8/article/details/78347172 摘要: JVM性能调优涉及到方方面面的取舍,往往是牵一发而动全身,需要全盘考虑各方面的 ...
- 如何合理的规划jvm性能调优
JVM性能调优涉及到方方面面的取舍,往往是牵一发而动全身,需要全盘考虑各方面的影响.但也有一些基础的理论和原则,理解这些理论并遵循这些原则会让你的性能调优任务将会更加轻松.为了更好的理解本篇所介绍的内 ...
- jvm 性能调优 经验总结---转
最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一记录. 一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老 ...
- JVM性能调优(转)
本文转自:http://www.cnblogs.com/chen77716/archive/2010/06/26/2130807.html 最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现 ...
- 使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码 (jvm性能调优)
技术交流群:233513714 本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 ...
随机推荐
- 华企盾防泄密软件关于U盘无法注册问题
1.以管理员权限运行控制台注册 2.如果是非加密注册可在USB拔插日志中右键日志远程注册 3.检查USB的驱动程序注册表是否都有 4.换一台电脑安装控制台注册 5.检查是否有与驱动有关的程序卸载试试 ...
- 聊聊流式数据湖Paimon(三)
概述 如果表没有定义主键,则默认情况下它是仅追加 表类型(Append Only Table). 根据桶(Bucket)的定义,我们有两种不同的仅追加模式:"Append For Scala ...
- Javascript Ajax总结——FormData类型
XMLHttpRequest1级只是把已有的XHR对象的实现细节描述出来.XMLHttpRequest2级进一步发展了XHR.FormData类型FormData类型,为序列化表单以及创建以表单格式相 ...
- Python笔记一之excel的读取
本文首发于公众号:Hunter后端 原文链接:Python笔记一之excel的读取 这里我常用的 python 对于 excel 的读取库有两个,一个是 xlsxwriter 用于操作 excel 的 ...
- P7112 【模板】行列式求值
学<高等代数>第二章的时候过来搜了搜模板,结果真搜到了.于是水一篇题解. 本文部分内容来自<高等代数>. 行列式定义 对于一个 \(n\) 阶行列式 \[A_{n \times ...
- 斯坦福 UE4 C++ ActionRoguelike游戏实例教程 09.第二个游戏规则:玩家重生
斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论 概述 本文对应课程15章,60 - Refining Player Respawns. 在本篇文章中,将会为游戏新增加 ...
- throws和try、catch有什么区别?throws如何使用?
在Java中,异常处理是非常重要的一部分.当程序出现异常时,我们需要对其进行处理以确保程序的正确性和可靠性.Java提供了两种异常处理机制:throws和try.catch. 区别 throws和tr ...
- 论文解读:ACL2021 NER | 基于模板的BART命名实体识别
摘要:本文是对ACL2021 NER 基于模板的BART命名实体识别这一论文工作进行初步解读. 本文分享自华为云社区<ACL2021 NER | 基于模板的BART命名实体识别>,作者: ...
- vue2.x老项目typescript改造过程经验总结
前言: 关于Vue2.x 的TS改造,其实没有啥好说的. 对于vue-cli项目来说,从新跑一遍 vue create xxx-project ,选择Manually select features ...
- 火山引擎ByteHouse:4000字总结,Serverless在OLAP领域应用的五点思考
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 作为云计算的下一个迭代,Serverless可以使开发者更专注于构建产品中的应用,而无需考虑底层堆栈问题.伴随着近 ...