AEM 线程转储分析
按照本文中详述的步骤和最佳实践,使用IBM线程分析器工具成功分析AEM Java线程转储。
描述 description
环境
Adobe Experience Manager
问题
如何使用IBM线程分析器工具分析AEM Java线程转储?
解决方法 resolution
-
下载并安装IBM线程分析器(简称为IBM TDA)。
-
从遇到性能问题的 AEM 实例中捕获线程转储。
-
在 IBM TDA 中打开线程转储。
-
要查看线程转储的详细信息,请选择列表中的文件,然后单击 线程详细信息 按钮。
-
按 栈栈深度 排序,最长栈栈位于顶部。
-
查看堆栈深度为 10 行或更长的线程。 这些通常是人们最感兴趣的线程。
在感兴趣的线程上做笔记。
-
按线程 状态 排序。
-
向下滚动到 可运行 线程。 可运行线程是在进行线程转储时大量占用 CPU 时间的线程。
注意:在查看 可运行 线程时,您可以忽略列在本页底部 Threads 部分的可忽略线程。
-
GET查找属于应用程序一部分的可运行线程,例如,后台作业线程或请求线程(请求线程的名称如下 — 127.0.0.1
[
1347028187737]
/content/sites/global/en/sitemap.static-delivery.httpd.html HTTP/1.1)。找到后,请一一单击这些线程。
-
对于每个请求线程,您可以通过查看线程名称中的时间戳来了解用户的浏览器何时向服务器发出请求。
例如,在以上线程名称中,时间戳(以毫秒unix epoch格式表示)为 1347028187737。
我们可以使用www.epochconverter.com将该纪元数转换为日期/时间。
每个线程转储都显示了它被占用时的日期和时间。
您可以通过请求时间和线程转储时间之间的时间差来查看请求活动的时间。
-
查看请求线程后,滚动浏览其他 可运行 线程。
找到感兴趣的可运行线程后,请查看中间面板 等待线程。
此处列出的Threads正在等待所选线程释放监视器。
如果您没有看到任何等待线程,那么您选择的线程可能仍然是锁的所有者(有关详细信息,请参见锁的实施类)。
例如,对于ReentrantReadWriteLock,您无法分辨哪个线程是锁的持有者,因为锁在内部实施了多个监视器。
因此,您可能必须查看源代码,将其与可能是锁持有者的线程匹配。
-
如果某个线程有许多其他线程正在等待的锁或监测器,那么请检查其余的线程转储,看看是否能找到有相同问题的其他线程。
查看其他转储中是否仍然存在相同的线程(在IBM TDA中,您可以选择多个线程转储并单击 比较Threads 按钮查看多个线程转储中的线程状态。
-
请参阅以下屏幕快照中的 收集器服务:
-
在此视图中,您可以跨多个线程转储查看线程,看看它是否是长时间运行的线程。
基本上,如果线程在多个转储中处于 可运行 状态并且具有长栈栈,那么这通常意味着它是一个长时间运行的线程。
-
如果您在查看 可运行 线程时没有找到太多内容,请返回线程列表,选择一个线程转储,然后单击顶部面板上的 监视器详细信息 按钮。
IBM TDA将打开一个窗口,显示拥有线程及其等待线程的监视器的树视图。
注意:它可能会显示一些线程池线程,如servlet引擎线程池监视器,可以忽略空闲线程。
您通常可以分辨某个线程是否是空闲线程池线程,因为大多数时候它们只有10个或更少的栈栈行。
线程级别CPU利用率(仅限Linux平台):
-
如果除了线程转储之外还捕获了
top -H -b -n1 -p <javapid>
输出,则可以交叉引用线程级别CPU利用率。打开顶部输出并获取正在使用CPU的线程的进程ID。
将进程ID转换为十六进制,然后在相应的线程转储文件中搜索该十六进制值。
ID应该与其中一个线程的 nid 匹配。
-
如果使用最多CPU的匹配线程是 VM线程 或任何 GC 线程,则可能有内存问题。
对更多线程转储和最高输出重复相同的练习,如果这些线程的模式占用了CPU时间,则说明存在内存问题。
-
如果您已确认内存问题,则请在下次出现问题时捕获栈转储。
有关捕获和分析栈转储的详细信息,请参阅此分析内存问题文章。
可忽略的
Threads:
- VM 线程:这是一个 VM 系统线程。
- 以 GC 任务线程开头的线程:这些是垃圾收集线程。
- 名称类似于
- [ 1347028691218] in code at java.net.PlainSocketImpl.socketAccept(Native Method)
的Threads:这些线程来自servlet引擎的线程池,等待新连接。