性能调优经验总结列表
- 关掉不必要的 log;
- log level 设置;
- 避免出 exception, 拿线程栈很耗 CPU;
you know you know, you know you don't know, and you don't know you don't know.
下载及设置
官方下载: https://www.eclipse.org/mat/
JDK 最好用最新的 JDK, 因为最新的基本优化最多.
根据你分析的 heap dump 的大小, 有时候需要调整 MAT 的 heap 的大小. 这个参数在 MAT 根目录的 MemoryAnalyzer.ini 文件里面. 我经常分析 30G 以下的 heap, 基本设置为 27G, 是 JVM 使用压缩指针来加速.
另外, 对于 HPROF 的 dump 来说, 我经常设置为非严格 parse, 因为有时候有点错误, 不影响分析:
文档: MAT 自带文档在 Help -> Help Contents 菜单里面, 或者在线版本的文档
分析
正常情况下当你打开一个 heap dump 之后, 它会问你是否自动诊断内存泄漏, 如果你不是为了诊断内存泄漏, 可以取消这步.
Histogram: 是按照类的实例数量聚集, 能很快发现包含大量实例的类. 一般情况下 char[] 或者 String 都在最上面, 这基本没有问题.
Dominator Tree: 对于诊断内存泄漏非常有用, 如果能抓到一个对象 dominate 很多实例, 基本你找到了问题所在.
OQL: 就像查询数据库的 SQL 语言, 非常方便的查找任何对象, 实例;
Threads: 查看当前heap的所有线程, 对于发现某个对象是怎么被创建, 或引用的非常有帮助.
更多关于如何使用 OQL: Java heap dump OQL samples - where
------ 未完待续 -------
jmap 用来输出 JVM 的heap 相关信息, 或者生成 heap dump. 可以对一个正在运行的 JVM 进程使用这个命令, 也可以对一个 core dump. 它的功能基本都被 jcmd 命令所替代
jmap -histo <pid> //jcmd <pid> help GC.class_histogram
jmap -histo:live <pid> //jcmd <pid> help GC.class_histogram -all
jmap -clstats <pid> //jcmd <pid> GC.class_stats
jmap -finalizerinfo <pid> //jcmd <pid> GC.finalizer_info
jmap -dump:format=b,file=/tmp/heapdump.hprfo <pid> //jcmd <pid> GC.heap_dump
jmap -dump:live,format=b,file=/tmp/heapdump.hprfo <pid> //jcmd <pid> GC.heap_dump -all
jhat 对 heap dump 分析, 然后起一个本地 web 服务器, 开 7000 端口, 使用户可以在浏览器通过 OQL 查看 heap 里面的信息. 因为功能不够强大, 基本都用其他工具, 比如 MAT 或 Java VisualVM.
两者都可以实现同步, 在有些方面二者还是有很多区别. synchronized 是 java 的一个语法级别的特性, ReentrantLock 是 util 里面的一个辅助类.
相同点:
不同点:
Java heap 是某个时间点上 JVM 内存的一个瞬时镜像(snapshot), 通过工具查看内存里面的各种对象以及他们之间的关系, 对于分析内存问题非常有帮助. 常见的 heap dump 都是二进制的 hprof 格式, 获得之后一般通过 jhat, JVisualVM 或者 MAT 分析. 那么第一步, 如何获得 heap dump 呢? 本文将介绍常见的获得 heap dump 的一些方法.
LM-SHC-16501315:Downloads xiatian$ jcmd
42596
98797 sun.tools.jcmd.JCmd
LM-SHC-16501315:Downloads xiatian$ jcmd 42596 GC.heap_dump /tmp/heap.hprof
42596:
Heap dump file created
LM-SHC-16501315:Downloads xiatian$ jmap -dump:live,format=b,file=/tmp/heapdump.hprof 42596
Dumping heap to /private/tmp/heapdump.hprof ...
Heap dump file created
JVisualVM
若在桌面环境, 并且已经安装 JDK, 可以使用 JDK 自带 GUI 工具 JVisualVM.
JConsole
JConsole 也是 JDK 自带 GUI 工具
可以在 JVM 启动时添加如下参数, 当发生 OOM 时候, 自动产生 heap dump:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>
public static void dumpHeap(String filePath, boolean live) throws IOException {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(
server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
mxBean.dumpHeap(filePath, live);
}
有时候, 你会看到 core dump 和 heap dump, 2个不一样的dump, 那么2个区别是什么呢?
Java 常见的三种 dump 文件: Core Dump, heap dump, thread dump