目录 start

  1. Java的性能调优
    1. JVM参数配置
      1. IDEA参数调优
    2. 内存优化
      1. 堆外内存
  2. 主要指标分析
    1. JDK自带工具
      1. jps
      2. jstat
      3. jinfo
      4. jmap
      5. jhat
      6. jstack
      7. jcmd
    2. 开源项目
      1. Arthas
    3. 图形化
      1. jvisualvm
      2. MAT
      3. IBM Heap Analyzer

目录 end|2019-10-19 17:04|


Java的性能调优

JVM参数配置

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

  • xxfoxJvm参数辅助工具

IDEA参数调优

1
2
3
4
5
6
7
8
9
10
11
12
-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目录下的工具

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阿里巴巴


vjtools唯品会


图形化

jvisualvm

Github:visualvm
visualgc plugin

参考博客: java内存泄漏的定位与分析


Local

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


Remote

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

参考博客: JVisualVM远程监控

jmx

jstatd

  1. vim jstatd.all.policy

    1
    2
    3
    4
    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

Official Doc: OQL Syntax

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

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

IBM Heap Analyzer

Official Site