使用javap来查看字节码

默认情况下打印所有非私有方法和字段

  • -p选项 还会打印私有方法和字段
  • -v选项 尽可能打印所有信息(这里指)
  • -c选项 只查看方法对应字节码

JOL工具

1
2
curl -L -O http://central.maven.org/maven2/org/openjdk/jol/jol-cli/0.9/jol-cli-0.9-full.jar
java -cp jol-cli-0.9-full.jar org.openjdk.jol.Main internals java.lang.String

jol地址已失效 -> 新地址

jvm调试命令

-XX:+

  • -XX:+UseCompressedOops

    开启对象压缩指针 64位 -> 32 位

这里使用内存对齐(8位)使后三位为0, 也可以用这3位来记录一些额外信息 扩大寻址范围32位->35位.

  • -XX:ObjectAlignmentLnBytes

    字节对齐 java虚拟机堆中的起始地址需要对齐至8的倍数

对象之间有内存对齐, 对象之间的字段也需要内存对齐(否则, 字段的读取需要替换两个缓存行, 存储会同时污染来那个缓存行, 影响执行效率)

jps

打印所有正在运行的进程的相关信息。

帮助文档

  • -m 将打印传递给Java虚拟机的参数
  • -l 将打印模块名以及包名
  • -v 将打印传递给 Java 虚拟机的参数(如-XX:+UnlockExperimentalVMOptions -XX:+UseZGC)

jstat

打印目标Java进程的性能数据。

帮助文档
$ jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation

例:

1
jstat -gc -t 22126 1s 4

jmap

分析虚拟机堆中的对象

帮助文档
-clstats
-finalizerinfo
-histo
-dump

例:

1
jmap -histo 22574

注意

以及jinfo、jstack和jcmd依赖于Java虚拟机的Attach API,因此只能监控本地Java进程
一旦开启Java虚拟机参数DisableAttachMechanism(-XX:+DisableAttachMechanism),基于Attach API的命令将无法执行。

远程跑java程序是否可以使用这些工具?

jinfo

jinfo命令可用来查看目标Java进程的参数,如传递给Java虚拟机的-X(即输出中的VM Flags),以及可在Java层面通过System.getProperty获取的-D参数(即输出中的System Properties)。
可以改动manageable的参数

帮助文档
例:

1
jinfo 73269

jstack

jstack命令可以用来打印目标Java进程中各个线程的栈轨迹,以及这些线程所持有的锁。

帮助文档
jstack的其中一个应用场景便是死锁检测。
jstack不仅会打印线程的栈轨迹、线程状态(BLOCKED)、持有的锁(locked …)以及正在请求的锁(waiting to lock …),而且还会分析出具体的死锁。

例:

1
jstack 73269

jcmd

可以使用jcmd命令,来代替除了jstat之外的所有命令。

帮助文档