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 ...
随机推荐
- JWT简单使用
创建一个Maven项目,并导入jar包 <?xml version="1.0" encoding="UTF-8"?> <project xml ...
- Educational Codeforces Round 159 总结
最失败的一集. C 开题顺序搞错,不小心先开了C,以为是A.还好C不难. 题意大概是在给定的数组最后添一个数(所有数两两不同),再自定义一个数 \(k\) ,数组中每个数可以加上若干个 \(k\) , ...
- 微服务网关限流&鉴权-wei-fu-wu-wang-guan-xian-liu--jian-quan
title: 微服务网关限流&鉴权 date: 2022-01-06 14:40:45.047 updated: 2022-01-06 14:40:45.047 url: https://ww ...
- 面试官:说一说你的第一个Java程序是怎么跑起来的
面试官:"说一说你第一个Java程序是怎么跑起来的?" 我:"啊,您是说Hello World吗?" 面试官:"嗯,没错,几十年过去了,还是hello ...
- node.js 命令必须加 npx 才能执行
问题描述 在 Windows 上搭建 Hexo 环境,已经从官网下载安装 node-v18.18.2-x64.msi,并且通过 npm 命令成功安装 hexo. PowerShell 中,直接执行 h ...
- 小熊派开发实践丨漫谈LiteOS之传感器移植
摘要:本文基于小熊派开发板简单介绍了如何在LiteOS中移植传感器,从而实现对于传感器的相关控制. 1 hello world 相信大家无论在学习编程语言开始的第一个函数应该是HelloWorld,本 ...
- SparkSQL高并发:读取存储数据库
摘要:实践解析如何利用SarkSQL高并发进行读取数据库和存储数据到数据库. 本文分享自华为云社区<SarkSQL高并发读取数据库和存储数据到数据库>,作者:Copy工程师 . 1. Sp ...
- appuploader 常规使用登录方法
转载:登录appuploader 登录appuploader 常规使用登录方法 双击appuploader.exe 启动appuploader 点击底部的未登录,弹出登录框 在登录框内输入ap ...
- 强强联合,ByteHouse 携手亚马逊云科技,新一代云数仓服务重磅升级
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着全球化的发展,越来越多的中国企业开始涉足海外市场,开展跨境业务.在这个过程中,强大的数据分析能力是出海企业不可 ...
- Solon Web 开发,十、签权
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...