Java 中的垃圾收集日志、线程转储、堆转储
Java 虚拟机 (JVM) 生成 3 个关键组件,这些组件对于优化性能和排除生产问题很有用。这些组件是:
- 垃圾收集 (GC) 日志
- 线程转储
- 堆转储
在本文中,让我们尝试了解这 3 个关键组件,它们在哪里使用,它的外观如何,如何捕获它们,如何分析它们以及它们的差异。
1.垃圾收集日志
a) 什么是 GC 日志?
GC Log 包含垃圾收集事件相关信息。它将指示运行了多少 GC 事件,它们是什么类型的 GC 事件(即 Young GC 或 Full GC),每个 GC 事件暂停应用程序的时间,每个 GC 事件回收了多少对象。
b) GC 日志看起来如何?
可以在此处找到示例垃圾收集日志文件。
c) GC Log 在哪里使用?
垃圾收集日志用于研究应用程序的 GC 和内存性能。它用于优化 GC 暂停时间,用于确定应用程序的最佳内存大小,还用于解决与内存相关的问题。
d) 如何生成GC日志?
您可以通过传递以下 JVM 参数来生成垃圾收集日志:
对于 8 之前的 Java 版本:
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:<file-path>
对于从 9 开始的 Java 版本:
-Xlog:gc*:file=<file-path>
文件路径:是垃圾收集日志文件将被写入的位置。
e) 如何理解GC Log?
垃圾收集日志格式因您的 JVM 供应商(Oracle、HP、IBM、Azul 等)、Java 版本(1.5、5、6、7、8、9、10、11、12……)、垃圾而异收集算法(串行、并行、CMS、G1、Shenandoah、Z GC)和传递的 JVM 参数。因此,没有一种可用的标准化格式。
f) 使用什么工具来分析 GC 日志?
有多种垃圾收集日志分析工具。这里给出了一些流行的:GCeasy、IBM GC 和内存可视化器、HP JMeter、Google Garbage Cat。
2.线程转储
a) 什么是线程转储?
线程转储是某个时间点在应用程序中运行的所有线程的快照。它包含有关应用程序中每个线程的所有信息,例如:线程状态、线程 ID、本机 ID、线程名称、堆栈跟踪、优先级。
b) 线程转储看起来如何?
可以在此处找到示例线程转储。
c) 线程转储在哪里使用?
线程转储主要用于解决生产问题,例如 CPU 峰值、应用程序无响应、响应时间差、线程挂起、内存消耗高。
d) 如何生成线程转储?
可以使用8 个不同的选项从正在运行的应用程序中捕获线程转储。进行线程转储的最常见选项是使用“jstack”工具。jstack 工具在 JDK_HOME\bin 文件夹中提供。这是您需要发出以捕获线程转储的命令:
jstack -l <pid> > <file-path>
其中pid:是应用程序的进程ID,应捕获其线程转储,而file-path:是将写入线程转储的文件路径。
e) 使用什么工具来分析线程转储?
以下是使用最广泛的线程转储分析工具:fastThread
、Samurai
、IBM Thread & Monitor Analyzer
、Visual VM
。
3.堆转储
a) 什么是堆转储?
堆转储是某个时间点应用程序内存的快照。它包含诸如内存中的对象是什么、它们携带什么值、它们的大小是多少、它们引用了哪些其他对象等信息。
b) 堆转储看起来如何?
可以在此处找到示例堆转储。(注意:它将采用二进制格式。因此您实际上无法读取它)。
c) 堆转储在哪里使用?
堆转储主要用于解决内存相关的 OutOfMemoryError 问题。
d) 如何生成堆转储?
可以使用7 个不同的选项从正在运行的应用程序中捕获堆转储。进行堆转储的最常见选项是使用“jmap”工具。jmap 工具在 JDK_HOME\bin 文件夹中提供。这是您需要发出以捕获的命令:
<span style="font-weight: 400;">jmap -dump:format=b,</span><span style="font-weight: 400;">
</span><span style="font-weight: 400;">file=<file-path> <pid> </span>
其中pid:是 Java 进程 ID,应捕获其堆转储,而file-path:是将写入堆转储的文件路径。
e) 如何理解堆转储?
堆转储文件采用二进制格式,并且往往很大。除此之外,它们的格式严重缺乏文档。因此,您必须使用堆转储分析工具(在下一个问题中给出)来分析和理解它们。
f) 使用什么工具来分析 Heap dump?
以下是使用最广泛的堆转储分析工具:Eclipse MAT
、HeapHero
、JVisualVM
。