【JVM】GC调优(优化JVM参数)、性能调优

GC调优

GC调优的主要目标是避免由垃圾回收引起程序性能下降。

GC调优的核心指标

  1. 垃圾回收吞吐量:执行用户代码时间/(执行用户代码时间 + GC时间)
  2. 延迟:GC延迟 + 业务执行时间
  3. 内存使用量

GC调优步骤

  1. 发现问题:通过监控工具。
  2. 诊断问题:通过分析工具。
  3. 修复问题:调整JVM参数或修复源代码。
  4. 测试验证

GC调优发现问题的工具

  1. jstat:jdk自带的可以提供垃圾回收的信息。 jstat -gc 进程ID 每次统计的间隔(毫秒) 统计次数。
  2. Visualvm插件:Visual GC插件,实时监控Java进程的堆内存结构、堆内存变化趋势以及垃圾回收时间的变化趋势。适合开发环境,对程序有影响,生产环境无权限。
  3. Prometheus + Grafana:非常详细,环境复杂,运维搭建。

分析GC日志

  1. GCViewer:日志转为可视化图表 java -jar gcviewer_1.3.4.jar 日志文件.log

https://github.com/chewiebug/GCViewer

  1. GCEasy:在线的可视化工具图表

https://gceasy.io/

常见的GC模式

  1. 正常情况
  2. 缓存对象过多
  3. 内存泄漏
  4. 持续的FullGC:请求量激增,生产更多对象,gc无法跟上对象创建速率。
  5. 元空间不足:堆中内存足够
图片1

GC调优的手段

  1. 优化基础JVM参数:基础JVM参数的设置不当,会导致频繁FULLGC的产生。
  2. 减少对象产生:大多数场景下的FULLGC是由于对象产生速度过快导致的。
  3. 更换垃圾回收器:选择适合当前业务场景的垃圾回收器,减少延迟、提高吞吐量。
  4. 优化垃圾回收器参数:

优化基础JVM参数

堆、栈、元空间、垃圾回收器、堆内存快照、日志

  1. -Xmx 和 –Xms 最大堆内存、初始堆内存。根据最大并发量估算服务器的配置,然后再减去系统和其他程序所需的内存。建议一样大,减少申请内存次数。
  2. -XX:MaxMetaspaceSize 和 -XX:MetaspaceSize 最大元空间大小、第一次FULLGC的阈值(之后JVM自行计算)。
  3. -Xss 虚拟机栈大小。默认大小取决于操作系统和体系结构。Linux x86 1m。合理值256k~1m。
  4. 不建议手动设置。
    1. -Xmn 年轻代的大小,默认值为整个堆的1/3。G1会动态调整年轻代大小。
    2. -XX:SurvivorRatio 伊甸园区和幸存者区的大小比例,默认值为8。
    3. -XX:MaxTenuringThreshold 最大晋升阈值,年龄大于此值,会进入老年代。JVM有动态年龄判断机制:将年龄从小到大的对象占据的空间加起来,如果大于survivor区域的50%,把等于或大于该年龄的对象,放入到老年代。
  5. 其他参数
    1. -XX:+DisableExplicitGC 禁止在代码中使用System.gc(),因为可能会引起FULLGC。
    2. -XX:+HeapDumpOnOutOfMemoryError 发生OOM错误时,自动生成hprof内存快照文件。
    3. -XX:HeapDumpPath= 指定hprof文件的输出路径。
    4. 打印GC日志:8及之前: -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:文件路径
    5. 打印GC日志:9及之后: -Xlog:gc*:file=文件路径

JVM参数模板

-Xms1g
-Xmx1g
-Xss256k
-XX:MaxMetaspaceSize=512m 
-XX:+DisableExplicitGC-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/logs/my-service.hprof-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-Xloggc:文件路径

实战

保存hprof文件,Heap Hero分析文件

https://heaphero.io/

性能调优

问题:top命令CPU占用率高;单个服务处理时间特别长;程序启动后正常,一段时间后无法处理任何请求。

线程转储

线程转储(Thread Dump)提供了对所有运行中的线程当前状态的快照。

jstack 进程id
jstack 进程id > 文件名  # 导出线程栈文件

线程转储的可视化在线分析平台: 1、 https://jstack.review/ 2、 https://fastthread.io/

CPU占用率高

  1. 通过top命令找到进程和线程。
  2. 使用jstack打印线程快照。
  3. 找到线程快照正在执行的方法,并优化性能。
top -c #找到进程id
top -p 进程id #再摁H可以查看进程的线程
jstack 进程id #查看栈信息
printf ‘%x\n’ #通过16进制,在文件中查看线程信息(文件中线程id是16进制)
# 找到栈信息中源代码位置

关注状态为RUNNABLE的线程。一些线程执行本地方法时并不会消耗CPU,只是在等待。但 JVM 仍然会将它们标识成“RUNNABLE”状态。

接口响应时间长

方法1:通过arthas的trace和watch命令,监控方法的执行耗时和参数、返回值等信息,定位性能瓶颈,并优化性能。

  1. trace 类名 方法名
  2. --skipJDKMethod false 输出JDK核心包中的方法及耗时。
  3. ‘#cost > 毫秒值’ 。
  4. –n 数值 ,最多显示该数值条。
  5. stop结束监控,重置arthas增强的对象。

方法2:通过arthas的profile火焰图功能,找到火焰图中顶部较平的方法,一般就是性能问题产生的根源,并优化性能。

  1. 使用了for循环向ArrayList中添加数据。ArrayList扩容需要copyof复制老到新的数组。

线程不可用、死锁

死锁或时间长:通过jstack、visualvm、fastthread.io 等工具,找到线程死锁的原因,解决死锁问题。

使用线程快照生成工具就可以看到死锁的根源。文件中搜索deadlock

https://fastthread.io/

解决思路:

1、检测是否有死锁产生,无法自动解除的死锁会将线程永远阻塞。

2、如果没有死锁,再使用案例1的打印线程栈的方法检测线程正在执行哪个方法,一般这些大量出现的方法就是慢方法。

判断方法耗时

使用OpenJDK中的jmh基准测试框架对某些特定的方法比如加密算法进行基准测试,jmh可以完全模拟运行环境中的Java虚拟机参数,同时支持预热能通过JIT执行优化后的代码获得更为准确的数据。注意添加黑洞消费,否则会被优化。

官网地址:https://github.com/openjdk/jmhc

Date 和 LocalDateTime

  • 52
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM参数是为了提高Java应用程序的性能和稳定性。下面是一些常见的JVM参数的思路和建议: 1. 堆内存设置: - -Xms: 初始堆大小,建议与-Xmx相同,避免堆大小的动态整。 - -Xmx: 最大堆大小,根据应用程序的需求进行设置,避免频繁的垃圾回收。 2. 垃圾回收器选择: - -XX:+UseParallelGC: 使用并行垃圾回收器,适合多核CPU和高吞吐量应用。 - -XX:+UseConcMarkSweepGC: 使用CMS垃圾回收器,适合响应时间先的应用。 - -XX:+UseG1GC: 使用G1垃圾回收器,适合大内存应用和低延迟要求。 3. 垃圾回收参数: - -XX:NewRatio: 设置新生代和老年代的比例,默认为2,可以根据应用程序的对象生命周期进行整。 - -XX:SurvivorRatio: 设置Eden区和Survivor区的比例,默认为8,可以根据对象的存活率进行整。 - -XX:MaxTenuringThreshold: 设置对象进入老年代的年龄阈值,默认为15,可以根据对象的存活率和内存情况进行整。 4. 线程相关参数: - -Xss: 设置线程栈的大小,默认为1M,可以根据应用程序的线程数量进行整。 - -XX:ParallelGCThreads: 并行垃圾回收的线程数量,默认为CPU核心数的1/8,可以根据CPU和内存情况进行整。 5. 其他常用参数: - -XX:+UseCompressedOops: 使用压缩指针,可以减少对象引用的内存消耗。 - -XX:+DisableExplicitGC: 禁用显示用System.gc()方法,避免不必要的垃圾回收。 以上是一些常见的JVM参数策略,具体的效果和最佳参数设置还需要根据应用程序的实际情况进行测试和整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值