Skip to content

JvmPerformance

kcp edited this page Oct 13, 2020 · 3 revisions

title: Jvm 性能调优 date: 2018-11-21 10:56:52 tags: - JVM categories: - Java

目录 start

  1. Java的性能调优
    1. JVM参数调优
      1. IDEA参数调优
    2. 内存优化
      1. 堆外内存
  2. 主要指标分析
    1. JDK自带工具
      1. java
        1. 环境变量的使用
        2. 执行含main方法的类
      2. jps
      3. jstat
      4. jinfo
      5. jmap
      6. jhat
      7. jstack
      8. jcmd
    2. 开源项目
      1. Arthas
      2. async-profiler
    3. 图形化
      1. JProfiler
      2. jvisualvm
      3. MAT
      4. IBM Heap Analyzer

目录 end|2020-08-03 01:00|


Java的性能调优

JVM参数调优

参考: JVM实用参数(一)JVM类型以及编译器模式

  • xxfoxJvm参数辅助工具

参考: JVM动态反优化
General Java Troubleshooting

IDEA参数调优

    -server
    -Xms600m  # 最小堆
    -Xmx600m  # 最大堆 配成一样是为了避免扩容
    -Xmn256m  # 新生代
    -XX:MetaspaceSize=350m # 只是一个阈值, 达到该阈值才进行 GC
    -XX:MaxMetaspaceSize=350m # 最大值

    -Xnoclassgc 
    -Xverify:none # 不进行字节码校验
    -XX:+AggressiveOpts # 激进式优化

    -XX:ReservedCodeCacheSize=320m # 编译时代码缓存 IDEA 警告不能低于240M

参考: Java’s -XX:+AggressiveOpts: Can it slow you down?
参考: JVM参数MetaspaceSize的误解


内存优化

堆外内存

堆外内存堆外内存主要是JNI、Deflater/Inflater、DirectByteBuffer(nio中会用到)使用的。


主要指标分析

JDK自带工具

都是jdk的bin目录下的工具

java

环境变量的使用

java [-options] -jar jarfile [args...]

What is the java -D command-line option good for?

  • 传入 java -Dkey=true -jar xxx.jar
    • -D 参数 要前于 -jar
  • 获取 System.getProperty("key", "defaultvalue");

执行含main方法的类

  • java -cp jarfile[:jarfile2] className

jps

主要用来输出JVM中运行的进程状态信息

  • option:
    • -q 忽略输出的类名、Jar名以及传递给main方法的参数,只输出pid。
    • -m 输出传递给main方法的参数,如果是内嵌的JVM则输出为null。
    • -l 输出应用程序主类的完整包名,或者是应用程序JAR文件的完整路径。
    • -v 输出传给JVM的参数。
    • -V 输出通过标记的文件传递给JVM的参数(.hotspotrc文件,或者是通过参数-XX:Flags=指定的文件)

jstat

  • option:

    • -gcutil 统计heap的gc情况
    • -t 在第一列输出时间戳。该时间戳从jvm启动开始
    • -h3 每隔N行输出一次列表头
    • $PID 进程号
    • interval 输出间隔时间,单位毫秒
    • count 输出次数
  • Demo:

    • jstat -gcutil -t -h5 7919 1000 50

jinfo

观察运行中的 java 进程的运行环境参数:参数包括 Java System 属性和 JVM 命令行参数

  • Demo:
    • jinfo 14352
    • jinfo -sysprops 14352
    • jinfo -flags 14352
    • jinfo -flag MaxPermSize 14352

jmap

用来查看堆内存使用状况

  • Demo:
    • jmap -histo $PID 展示class的内存情况
    • jmap -heap $PID 展示Java堆详细信息
    • jmap -dump:live,format=b,file=heapLive.hprof 2576

jhat

Java Head Analyse Tool

用于分析 jmap 转储出来的堆文件, 分析完后启动一个WebServer 通过浏览器查看

jstack

jstack [option] pid 主要用来查看某个Java进程内的线程堆栈信息

  • Option:

    • -F: 强制产生一个线程dump
    • -m: 打印java和native frames
    • -l: 打印关于锁的附加信息
  • 找出占用CPU最高的线程:

    1. jps 或者 ps aux | grep xxx 得到想要的Java进程id
    2. top -Hp 进程id 查看 time 占用最长 或者 CPU占用最高 的线程
    3. printf %x 线程id 得到 16进制 线程id
    4. jstack 进程id | grep -A 20 16进制线程id 查看该线程的栈,进而分析到代码

jcmd


开源项目

Arthas

Github: Arthas阿里巴巴

async-profiler

async-profiler


vjtools唯品会


图形化

JProfiler

Official Site

GCViewer

Github: GCViewer

jvisualvm

Github:visualvm
visualgc plugin

参考: java内存泄漏的定位与分析 使用 VisualVM 进行性能分析及调优
参考: JVisualVM简介与内存泄漏实战分析

  • Local
  • Remote
    • 通常使用两种方式连接远程JVM: JMX jstatd

    • jmx

    • jstatd

      1. vim jstatd.all.policy
            grant codebase "file:${java.home}/../lib/tools.jar" {
                permission java.security.AllPermission;
        
            };
        
      2. jstatd -J-Djava.security.policy=jstatd.all.policy -p 12028 -J-Djava.rmi.server.logCalls=true
      3. open jvisualvm create a remote with jstatd by above port 12028

MAT

Memory Analyzer tool(MAT) | Official Site

参考: JAVA Shallow heap & Retained heap
参考: 利用MAT分析JVM内存问题,从入门到精通
Official Doc: OQL Syntax

他的 OQL 比较方便, 像写 SQL 一样去查询对象

注意: 有这样的一种场景, 从数据库获取大量的数据创建为对象, 导致瞬间的OOM 这时候即使使用 jmap 去 dump 了快照, 也看不到占用大量内存的对象, 很有可能这些对象就是gc不可达的, 而mat只能分析可达对象

IBM Heap Analyzer

Official Site

Summary

Clone this wiki locally