凌月风的个人博客

记录精彩人生

Open Source, Open Mind,
Open Sight, Open Future!
  menu

Java笔记系列——01-Java虚拟机(3)

0 浏览

JVM参数

  • 参数类型

    • 布尔类型

      • 开: -XX:+<option>
      • 关:-XX:-<option>
    • 字符类型:-XX:<option>=<string>

    • 数值类型:-XX:<option>=<number> 数值可以包括m、M、k、K、g、G

  • 参数简写

    • ‐Xms1000M 等价于 ‐XX:InitialHeapSize=1000M
    • ‐Xmx1000M 等价于 ‐XX:MaxHeapSize=1000M
    • ‐Xss100 等价于 ‐XX:ThreadStackSize=100
  • JVM参数说明《Java HotSpot VM Options (oracle.com)》

  • Java参数文档《java (oracle.com)》


  • 参数设置

    • 开发工具中设置比如 IDEA,eclipse
    • 运行jar包的时候:java -XX:+UseG1GC xxx.jar
    • 中间件比如tomcat,可以在脚本中的进行设置
    • 通过jinfo实时调整某个java进程的参数(参数只有被标记为 manageable 的 flags 可以被实时修改)

  • 查看参数

    • 启动java进程时添加:-XX:+PrintFlagsFinal参数

    • 通过jinfo命令查看:

      jinfo [ option ] pid
      jinfo [ option ] executable core
      jinfo [ option ] [server-id@]remote-hostname-or-IP 
      

  • 常用命令

    • jps

      jps
      jps ‐l
      
      • jinfo

        jinfo ‐flag name PID 
        jinfo ‐flag <name>=<value> PID 
        jinfo ‐flags PID
        
      • jstat

        jstat ‐class PID 1000 10    //查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次
        jstat ‐gc PID 1000 10
        
      • jstack(查询死锁)

        jstack PID
        
      • jmap

        jmap ‐heap PID 
        jmap ‐dump:format=b,file=heap.hprof PID 
        ‐XX:+HeapDumpOnOutOfMemoryError ‐XX:HeapDumpPath=D:/heap.hprof   // OOM发生时自动dump文件到某个目录
        

工具

  • 通用型工具:可以查看内存基本情况、进程情况、垃圾回收情况等

    • jconsole :JDK自带的可视化监控工具。查看java应用程序的运行概况、监控堆信息、永久区使用情况、类加载情况等。
    • jvisualvm:可以监控某个java进程的CPU,类,线程等
    • Arthas
      1. 下载 https://alibaba.github.io/arthas/arthas‐boot.jar
      2. 启动:java ‐jar arthas‐boot.jar

  • 内存分析型工具

    • 基于dump文件进行分析,获取dump文件:

      jmap ‐dump:format=b,file=heap.hprof 44808‐XX:+HeapDumpOnOutOfMemoryError ‐XX:HeapDumpPath=heap.hprof

    • MAT:Java堆分析器,用于查找内存泄漏

    • HeapHero:https://heaphero.io/

    • Perfma:https://console.perfma.com


  • 垃圾收集分析工具

    • 基于GC日志进行分析,获取GC日志:

      ‐XX:+PrintGCDetails ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps ‐Xloggc:D:\gc.log

    • gcviewer:java ‐jar gcviewer‐1.36‐SNAPSHOT.jar

    • gceasy: http://gceasy.io

    • gcplot(基于docker):https://it.gcplot.com/

调优

  • JVM 的性能优化可以分为代码层面和非代码层面。
    • 代码层面,可以结合字节码指令进行优化,比如一个循环语句,可以将循环不相关的代码提取到循环体之外, 这样在字节码层面就不需要重复执行这些代码了。
    • 非代码层面,一般情况可以从参数、内存、GC以及cpu占用率等方面进行优化。

  • 确定需要调优的场景
    • 查看CPU占用率高,需要调优
      1. top(查看占用CPU高的进程ID,即pid)
      2. top ‐Hp PID(查看进程中占用CPU高的线程id,即tid)
      3. jstack PID | grep tid(1) (查看进程中的某个线程占用信息)
    • 发生OOM调优
      • 连续分配对象得不到及时回收(死循环向列表添加对象)
      • 并发场景过多(ThreadLocal线程过多)
      • 有些资源未及时释放

  • 参数调优
    • JVM参数说明《Java HotSpot VM Options (oracle.com)》
    • ‐XX:MaxTenuringThreshold // 晋升到老年代的年龄阈值设置,默认15
    • ‐XX:PretenureSizeThreshold=0 // 超过多大的对象直接在老年代分配 ,单位为字节,比如:‐XX:PretenureSizeThreshold=10*1024*1024 代表超过10M就放到Old区
    • ‐XX:+/‐ UseAdaptiveSizePolicy // Enables the use of adaptive generation sizing. This option is enabled by default.
    • ‐Xms和‐Xmx (两者值一般设置成一样大,防止内存空间进行动态扩容)

  • G1 GC调优实例

    • 调优追求的目标是低停顿、高吞吐量、少回收次数,在这之间寻求平衡

    • 分析

      1. 获取GC日志文件:-XX:+UseG1GC -Xloggc:g1-gc.log

      2. 选择工具分析日志(查看第9章的工具)

      3. 吞吐量和停顿时间是两个重要指标,还有垃圾回收次数

      4. 比如分析之后摘出数据为:

        吞吐量				停顿时间		回收次数
        96.97%			   3.12 ms		    22
        
    • 调优

      1. 调整内存空间变大,然后继续分析
      2. 设置 停顿时间-XX:MaxGCPauseMills=3
      3. 降低停顿时间会增大回收次数,G1建议在200ms左右即可
      4. 使用-XX:ConcGCThreads=n来增加垃圾回收线程的数量
      5. 启动并发GC时堆内存占用百分比:-XX:InitiatingHeapOccupancyPercent=45
    • 官方建议

      1. 不要手动设置新生代和老年代的大小,只要设置整个堆的大小
      2. 不断调优暂停时间目标(不要对停顿时间太苛刻,否则会增加回收次数)
      3. 文档地址1:Troubleshooting and Diagnostic Guide for JavaTM 2 Platform, Standard Edition 5.0 (oracle.com)
      4. 文档地址1:Frequently Asked Questions About the Java HotSpot VM (oracle.com)

  • 注意,JVM调优是一个漫长和复杂的过程,而在很多情况下,JVM是不需要优化的,因为JVM本身已经做了很多的内 部优化操作,千万不要为了调优而调优
  • 汇总脑图
    image-20220514221510721
image/svg+xml