• JVM调优实操步骤


    前置知识

    1、堆中各大小的参数设置

    -Xms32M 初始堆大小

    -Xmx32M 最大堆大小

    -Xmn16M 新生代大小

    -XX:MetaspaceSize=256M 设置元空间的初始值

    -XX:MaxMetaspaceSize=256M 设置最大元空间大小

    -XX:SurvivorRatio=8 设置Eden和survivor的比例

     

    2、垃圾收集器的选择

    -XX:+UseSerialGC 使用serial & serialOld

    -XX:+UseParallelGC 使用 Parallel Scavenge & ParallelOld

    -XX:+UseConcMarkSweepGC 使用 ParNew & CMS

    -XX:+UseG1GC 使用G1垃圾收集器

     

    3、开启GC日志

    ---JDK8:

    • -XX:+PrintGCDetails
    • -XX:+PrintGCDateStamps
    • -Xloggc:D:\gc\gc-%t.log
    • -XX:+UseGCLogFileRotation
    • -XX:NumberOfGCLogFiles=2
    • -XX:GCLogFileSize=1M

    JDK9---:

    • -Xlog:gc=debug:file=gc.log:uptimemillis,pids:filecount=5,filesize=1024

     

    4、开启OOM的时候触发快照

    1、自动

    • -XX:+HeapDumpOnOutOfMemoryError
    • -XX:HeapDumpPath=/usr/local

    2、如果没有开启可手动

    • jmap -dump:format=b,file=名称.hprof

     

    5、GCeasy,在线人工智能分析GC日志

    1. 吞吐量
    2. GC延迟信息(平均值、最高值、用时分布)
    3. GC次数,GC原因
    4. 各区内存使用的峰值
    5. GC后的堆内存大小连续图(整堆、年轻代、老年代、元空间)
    6. GC前的对内存大小连续图(整堆、年轻代、老年代、元空间)
    7. GC回收垃圾连续图
    8. GC原因列表

    6、OOM类型

    1. java heap space 堆内存溢出,根据dump快照分析可疑对象,定位代码进行解决
    2. Metaspace ①动态创建的类太多,利用jstack查看堆栈信息,定位代码。②空间设置过小,增加空间
    3. GC over head limit excepted 默认情况下,jvm用了98%的时间回收垃圾,回收效果不到%2,(内存泄漏、大对象或者长生命周期对象导致的)
    4. Direct Buffer Memory,①直接内存设置过小(-XX:MaxDirectMemorySize 默认64M) ②使用直接内存的时候没有释放
    5. unable to create new native thread,①查看堆栈,确定线程数,不多就查看系统允许的线程数,多就去查看什么线程创建过多,定位代码,分析解决
    6. request {} byte for {} out of swap 使用到了直接内存,分析是否内存泄漏,分析大对象或者长期存活对象,定位代码,进行解决

     

    调优思维

    1. 首先不对JVM各区大小进行设置,使用默认值,开启GC日志,开启OOM的时候触发快照
    2. 运行一段时间,利用GCeasy分析GC日志,在正常运行的情况下,获取到FullGC后的老年代的大小(OldSizeAfterFullGC)
    3. 设置-Xms和-Xmx的大小为 3~4 倍 的 OldSizeAfterFullGC
    4. 设定-Xmn的大小为 1~1.5倍的 OldSizeAfterFullGC
    5. 设定-XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 大小为 FullGC后的元空间使用大小的 1.2~1.5倍
    6. 继续运行
    7. 分析日志,如果MinorGC过于频繁则增加 -Xmn的大小,如果MinorGC的间隔时间太长,则减少新生代的大小,具体测试决定

     

    线上解决频繁FullGC问题

    1. 利用GCeasy分析GC日志
    2. 了解整体性能(吞吐量、GC延迟)
    3. 查看FullGC频率,确定是频繁FullGC
    4. 查看FullGC的原因,杜绝手动调用System.gc()
    5. 查看元空间在GC前后的占用空间的统计图,确定是否因为元空间被打满导致的频繁FullGC
    6. 查看整堆在GC后的占用空间统计图,看是否持续上涨,如果是是内存泄漏问题
    7. 查看垃圾回收数据量的统计图,确定是否回收了数据,如果回收了数据,但是堆数据还是持续上涨到最大值,考虑是死循环,使用top查看高CPU占用进程获取pid,使用top -Hp pid获取进程内高cpu占用的线程pid,printf "%x\n" pid 将线程pid转换为16进制,用jstack 去dump指定进程,根据线程pid找到数据,定位代码,进行分析
    8. 回收没有效果,dump堆内存,利用MAT工具进行分析,定义可疑大对象或者长期存活的对象,定位到代码,进行分析
  • 相关阅读:
    迪杰斯特拉算法
    基数排序
    快排算法
    插入排序与希尔排序算法
    java--jmm知识
    Java基础
    socket代理
    TestLink 学习第一周
    软件体系结构第三章之解释器风格
    如何衡量个人在各自团队的效率和绩效
  • 原文地址:https://www.cnblogs.com/tiancai/p/16040645.html
Copyright © 2020-2023  润新知