Kevin's blog Kevin's blog
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档

Kevin

你可以迷茫,但不可以虚度
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档
  • JVM性能调优

    • JVM类的加载机制
    • JVM内存模型
    • JVM对象创建与内存分配机制
    • JVM垃圾收集算法
    • JVM垃圾收集器
    • JVM调优工具以及调优实战
      • JVM参数调优
        • JVM参数解析:
        • JVM参数分析:
      • 输出GC日志
      • Arthas
        • Arthas指标分析:
        • 调优建议:
      • jvm调优命令工具
        • jps查看进程ID
        • jmap
        • jstack
        • jinfo
        • jstat
      • 相关文章
    • 字节码与操作数栈
    • GCLog分析
    • JVM 内存分析工具 MAT及实践
  • 并发编程

  • MySql

  • spring

  • redis

  • zookeeper

  • rabbitMQ

  • 架构

  • 锁

  • 分库分表

  • 学习笔记
  • JVM性能调优
kevin
2022-05-10
目录

JVM调优工具以及调优实战

# 调优工具以及调优实战

# JVM参数调优

java -XX:+UseContainerSupport -XX:MaxRAMPercentage=60.0 -XX:InitialRAMPercentage=60.0 -XX:MinRAMPercentage=60.0 -XX:NewRatio=2 -Xss512k -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=512M -Djava.awt.headless=true -d64 -server -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Djavax.servlet.request.encoding=UTF-8 -Dfile.encoding=UTF-8 -XX:+AlwaysPreTouch -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/demo-api/logs/demo-api/ -jar demo-api-1.0.1-RELEASE.jar --server.port=8080 --management.server.port=8070 --apollo.meta=http://configserver:8080
1
  1. -XX:+UseContainerSupport: 启用容器支持,允许JVM自动检测容器环境并调整内存使用以适应容器的限制。
  2. -XX:MaxRAMPercentage=60.0: 设置JVM可用内存的最大百分比为60%,限制JVM在物理内存中可以使用的最大比例。
  3. -XX:InitialRAMPercentage=60.0: 设置JVM初始内存的百分比为60%,用于指定JVM在启动时分配的内存比例。
  4. -XX:MinRAMPercentage=60.0: 设置JVM最小内存的百分比为60%,指定JVM在运行时所需的最小内存比例。
  5. -XX:NewRatio=2: 表示新生代和老年代的比例为 1:2,也就是新生代占整个堆内存的1/3,而老年代占2/3。
  6. -Xss512k: 设置线程栈的大小为512KB,影响每个线程的栈大小。
  7. -XX:MetaspaceSize=256M: 设置Metaspace的初始大小为256MB。
  8. -XX:MaxMetaspaceSize=512M: 设置Metaspace的最大大小为512MB。
  9. -Djava.awt.headless=true: 设置Java运行时为无头模式,用于在没有图形界面的环境中运行。
  10. -d64: 指示JVM在64位模式下运行。
  11. -server: 指示JVM以服务器模式运行,通常用于生产环境,以获得更好的性能。
  12. -Djava.net.preferIPv4Stack=true: 设置JVM偏好使用IPv4协议栈。
  13. -Djavax.servlet.request.encoding=UTF-8: 设置Servlet请求的编码为UTF-8。
  14. -Dfile.encoding=UTF-8: 设置文件编码为UTF-8。
  15. -XX:+AlwaysPreTouch: 指示JVM在启动时分配并预触摸所有堆内存,以确保内存已分配。
  16. -XX:+UseConcMarkSweepGC: 启用并发标记清除垃圾收集器(Concurrent Mark-Sweep GC)。
  17. -XX:CMSInitiatingOccupancyFraction=75: 设置CMS垃圾收集器的触发阈值为75%。
  18. -XX:+UseCMSInitiatingOccupancyOnly: 使用CMS的触发阈值来触发垃圾收集,而不使用其他条件。
  19. -XX:+HeapDumpOnOutOfMemoryError: 在发生内存溢出错误时生成堆转储文件。
  20. -XX:HeapDumpPath=/demo-api/logs/demo-api/: 指定堆转储文件的保存路径为/demo-api/logs/demo-api/。
  21. -jar demo-api-1.0.1-RELEASE.jar: 启动一个包含demo-api-1.0.1-RELEASE.jar的Java应用程序。
  22. --server.port=8080: 指定应用程序的HTTP端口为8080。
  23. --management.server.port=8070: 指定管理端口为8070。
  24. --apollo.meta=http://configserver:8080: 指定Apollo配置中心的元数据地址为http://configserver:8080。

参数调优

-XX:MetaspaceSize=200M -XX:MaxMetaspaceSize=400M -XX:+UseContainerSupport -XX:MaxRAMPercentage=50.0 -XX:InitialRAMPercentage=50.0 -XX:MinRAMPercentage=50.0 -Xss512k -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/
1

# JVM参数解析:

  1. -XX:MetaspaceSize=200M: 设置Metaspace的初始大小为200MB。Metaspace是Java 8及更高版本中用于存储类元数据的区域。
  2. -XX:MaxMetaspaceSize=400M: 设置Metaspace的最大大小为400MB。这是Metaspace允许增长到的最大大小。
  3. -XX:+UseContainerSupport: 启用容器支持。这个选项允许JVM自动检测容器环境并调整内存使用,以便更好地适应容器的限制。
  4. -XX:MaxRAMPercentage=50.0: 设置JVM可用内存的最大百分比为50%。这个选项用于限制JVM在整个物理内存中可以使用的最大比例。
  5. -XX:InitialRAMPercentage=50.0: 设置JVM初始内存的百分比为50%。这个选项用于指定JVM在启动时分配的内存比例。
  6. -XX:MinRAMPercentage=50.0: 设置JVM最小内存的百分比为50%。这个选项用于指定JVM在运行时所需的最小内存比例。
  7. -Xss512k: 设置线程栈的大小为512KB。这影响每个线程的栈大小。
  8. -XX:+UseConcMarkSweepGC: 启用并发标记清除垃圾收集器(Concurrent Mark-Sweep GC)。这是一种用于管理Java堆内存中的垃圾的垃圾收集器。
  9. -XX:CMSInitiatingOccupancyFraction=75: 设置CMS(Concurrent Mark-Sweep)垃圾收集器的触发阈值为75%。当堆内存占用达到这个阈值时,CMS开始执行垃圾收集。
  10. -XX:+UseCMSInitiatingOccupancyOnly: 使用CMS的触发阈值来触发垃圾收集,而不使用其他条件。
  11. -XX:+HeapDumpOnOutOfMemoryError: 在发生内存溢出错误时生成堆转储(heap dump)文件。堆转储文件包含了内存中的对象快照,用于分析问题。
  12. -XX:+CMSParallelRemarkEnabled:并行执行CMS的remark阶段。
  13. -XX:+ScavengeBeforeFullGC:在执行Full GC之前先执行Minor GC。
  14. -XX:+CMSScavengeBeforeRemark:在CMS的remark阶段之前先执行Minor GC。
  15. -XX:ParallelCMSThreads=4:并行执行CMS的线程数设置为4。
  16. -XX:HeapDumpPath=/tmp/: 指定堆转储文件的保存路径为/tmp/。堆转储文件将保存在该目录下。

# JVM参数分析:

  1. Metaspace: 为Metaspace设置的初始大小为200M,最大大小为400M。这通常是足够的,除非有很多动态生成的类或使用了大量的第三方库。
  2. RAM使用: 设置了UseContainerSupport,这意味着JVM会考虑容器的限制。为JVM堆设置的RAM百分比是50%,这意味着JVM会使用容器可用RAM的50%作为其最大堆大小。
  3. 线程堆栈大小: 设置的线程堆栈大小为512k,这对大多数应用程序来说是足够的。
  4. GC: 您选择了UseConcMarkSweepGC,这是一个并发标记-清除垃圾收集器,适用于响应时间要求严格的应用程序。
  5. Heap Dump: 在OutOfMemoryError时,选择了生成堆转储,并将其保存在/tmp/目录下。

# 输出GC日志

# 必备
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+PrintTenuringDistribution 
-XX:+PrintHeapAtGC 
-XX:+PrintReferenceGC 
-XX:+PrintGCApplicationStoppedTime

# 可选
-XX:+PrintSafepointStatistics 
-XX:PrintSafepointStatisticsCount=1

# GC日志输出的文件路径
-Xloggc:/path/to/gc-%t.log
# 开启日志文件分割
-XX:+UseGCLogFileRotation 
# 最多分割几个文件,超过之后从头文件开始写
-XX:NumberOfGCLogFiles=14
# 每个文件上限大小,超过就触发分割
-XX:GCLogFileSize=100M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# Arthas

# dashboard

image-20230918140356378

# Arthas指标分析:

  1. 操作系统: 您的操作系统是Linux,版本为5.4.253-167.359.amzn2.x86_64,JVM版本为1.8.0_265。
  2. 线程: 大部分线程的CPU使用率都很低,没有明显的CPU瓶颈。
  3. 内存:
    • 堆内存使用了732M,总共1013M,这意味着您的应用程序使用了大约72%的堆内存。
    • Eden区使用了135M,总共320M。
    • Old区使用了591M,总共683M。
    • 非堆内存使用了238M,总共254M。
    • Metaspace使用了154M,总共167M。
  4. GC:
    • 年轻代GC(ps_scavenge)运行时间为10647ms。
    • 老年代GC(ps_marksweep)运行了23次,总时间为10488ms。

# 调优建议:

  1. 内存调整: 考虑到堆内存使用了大约72%,可以考虑增加MaxRAMPercentage的值,例如设置为60%或70%,以提供更多的堆内存给应用程序。
  2. GC策略: 当前使用的是CMS垃圾收集器,如果发现应用程序的响应时间受到GC的影响,可以考虑切换到G1垃圾收集器,它在Java 8中也是可用的,并且通常提供更好的响应时间。
  3. Metaspace: 考虑到Metaspace使用了接近其上限的内存,您可以考虑增加MaxMetaspaceSize的值,例如设置为500M。
  4. 监控: 继续使用Arthas或其他监控工具来监控应用程序的性能,特别是GC活动和内存使用情况。
  5. 代码优化: 考虑对应用程序代码进行性能分析,找出可能的瓶颈或不必要的资源使用,并进行优化。

# jvm调优命令工具

# jps查看进程ID

# jmap

JVM Memory Map命令用于生成heap dump文件,还可以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等

jmap pid

参数如下:
-heap:打印jvm heap的情况
-histo:打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。
-histo:live :只打印存活对象的情况
-permstat:打印permanent generation heap情况

  • jmap -histo pid

    • 查看内存信息,实例个数以及占用内存大小
  • jmap -heap pid

    • 堆信息
  • jmap ‐dump:format=b,file=eureka.hprof 14660

    • 堆内存dump

# jstack

用于查看线程状态

  • jstack pid

    • jstack加进程id查找死锁
  • jstack找出占用cpu最高的线程堆栈信息

    1. 使用命令top -p <pid> ,显示你的java进程的内存情况,pid是你的java进程号,比如19663
    2. 按H,获取每个线程的内存情况
    3. 找到内存和cpu占用最高的线程tid,比如19664
    4. 转为十六进制得到 0x4cd0,此为线程id的十六进制表示
    5. 执行 jstack 19663|grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调 用方法
    6. 查看对应的堆栈信息找出可能存在问题的代码

# jinfo

用来查看正在运行的java应用程序的扩展参数(JVM中-X标示的参数),甚至支持在运行时修改部分参数。

  • jinfo -flags pid

    • 查看jvm的参数
  • jinfo -sysprops pid

    • 查看jvm的参数

# jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。 命令的格式如下: jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]

  • jstat -gc pid

    • 可以评估程序内存使用及GC压力整体情况
    • S0C:第一个幸存区的大小,单位KB
    • S1C:第二个幸存区的大小
    • S0U:第一个幸存区的使用大小
    • S1U:第二个幸存区的使用大小
    • EC:伊甸园区的大小
    • EU:伊甸园区的使用大小
    • OC:老年代大小
    • OU:老年代使用大小
    • MC:方法区大小(元空间)
    • MU:方法区使用大小
    • CCSC:压缩类空间大小
    • CCSU:压缩类空间使用大小
    • YGC:年轻代垃圾回收次数
    • YGCT:年轻代垃圾回收消耗时间,单位s
    • FGC:老年代垃圾回收次数
    • FGCT:老年代垃圾回收消耗时间,单位s
    • GCT:垃圾回收消耗总时间,单位s
  • jstat -gccapacity pid

    • 堆内存统计
    • NGCMN:新生代最小容量
    • NGCMX:新生代最大容量
    • NGC:当前新生代容量
    • S0C:第一个幸存区大小
    • S1C:第二个幸存区的大小
    • EC:伊甸园区的大小
    • OGCMN:老年代最小容量
    • OGCMX:老年代最大容量
    • OGC:当前老年代大小
    • OC:当前老年代大小
    • MCMN:最小元数据容量
    • MCMX:最大元数据容量
    • MC:当前元数据空间大小
    • CCSMN:最小压缩类空间大小
    • CCSMX:最大压缩类空间大小
    • CCSC:当前压缩类空间大小
    • YGC:年轻代gc次数
    • FGC:老年代GC次数
  • jstat -gcnew pid

    • 新生代垃圾回收统计
    • S0C:第一个幸存区的大小
    • S1C:第二个幸存区的大小
    • S0U:第一个幸存区的使用大小
    • S1U:第二个幸存区的使用大小
    • TT:对象在新生代存活的次数
    • MTT:对象在新生代存活的最大次数
    • DSS:期望的幸存区大小
    • EC:伊甸园区的大小
    • EU:伊甸园区的使用大小
    • YGC:年轻代垃圾回收次数
    • YGCT:年轻代垃圾回收消耗时间
  • jstat -gcnewcapacity pid

    • 新生代内存统计
    • NGCMN:新生代最小容量
    • NGCMX:新生代最大容量
    • NGC:当前新生代容量
    • S0CMX:最大幸存1区大小
    • S0C:当前幸存1区大小
    • S1CMX:最大幸存2区大小
    • S1C:当前幸存2区大小
    • ECMX:最大伊甸园区大小
    • EC:当前伊甸园区大小
    • YGC:年轻代垃圾回收次数
    • FGC:老年代回收次数
  • jstat -gcold pid

    • 老年代垃圾回收统计
    • MC:方法区大小
    • MU:方法区使用大小
    • CCSC:压缩类空间大小
    • CCSU:压缩类空间使用大小
    • OC:老年代大小
    • OU:老年代使用大小
    • YGC:年轻代垃圾回收次数
    • FGC:老年代垃圾回收次数
    • FGCT:老年代垃圾回收消耗时间
    • GCT:垃圾回收消耗总时间
  • jstat -gcoldcapacity pid

    • 老年代内存统计
    • OGCMN:老年代最小容量
    • OGCMX:老年代最大容量
    • OGC:当前老年代大小
    • OC:老年代大小
    • YGC:年轻代垃圾回收次数
    • FGC:老年代垃圾回收次数
    • FGCT:老年代垃圾回收消耗时间
    • GCT:垃圾回收消耗总时间
  • jstat -gcmetacapacity pid

    • 元数据空间统计
    • MCMN:最小元数据容量
    • MCMX:最大元数据容量
    • MC:当前元数据空间大小
    • CCSMN:最小压缩类空间大小
    • CCSMX:最大压缩类空间大小
    • CCSC:当前压缩类空间大小
    • YGC:年轻代垃圾回收次数
    • FGC:老年代垃圾回收次数
    • FGCT:老年代垃圾回收消耗时间
    • GCT:垃圾回收消耗总时间
    • S0:幸存1区当前使用比例
    • S1:幸存2区当前使用比例
    • E:伊甸园区使用比例
    • O:老年代使用比例
    • M:元数据区使用比例
    • CCS:压缩使用比例
    • YGC:年轻代垃圾回收次数
    • FGC:老年代垃圾回收次数
    • FGCT:老年代垃圾回收消耗时间
    • GCT:垃圾回收消耗总时间

# 相关文章

Java中9种常见的CMS GC问题分析与解决 (opens new window)

从实际案例聊聊Java应用的GC优化 (opens new window)

上次更新: 2024/04/01, 19:14:44
JVM垃圾收集器
字节码与操作数栈

← JVM垃圾收集器 字节码与操作数栈→

最近更新
01
AI是如何学习的
06-05
02
chatGpt提示原则
06-05
03
提示词工程实践指南
06-05
更多文章>
| Copyright © 2022-2025 Kevin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式