6

使用 JRockit,您可以通过任何方式获取完整的线程列表,所有这些方式都包括有关垃圾收集线程的信息:

1)向Thread班级询问信息:

Thread.getAllStackTraces();

2)ThreadGroup用于获取该信息:

ThreadGroup root = Thread.currentThread().getThreadGroup();
while (root.getParent() != null) {
    root = root.getParent();
}
Thread[] list = new Thread[root.activeCount() + 5];
root.enumerate(list, true);

3)使用JMX获取列表:

ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean();
long[] tids = THREAD_MX_BEAN.getAllThreadIds();
ThreadInfo[] tinfos = THREAD_MX_BEAN.getThreadInfo(tids);

4) CTRL-BREAK

然而,使用 Sun JVM——至少是最近的 Java 6 版本——只有 CTRL-BREAK 似乎包括垃圾收集线程和 VM 定期任务线程。我发现监视 GC 线程使用的 CPU 很有用,因此我的应用程序可以检测和记录 GC 何时使用大部分 CPU 时间。如果没有这些信息,您只能知道 GC 何时超过某些设置的阈值。

如果我什至可以找出 GC 线程的线程 ID,那么 JMX 可能会提供我需要的其余信息(除非这些线程有什么不同)。例如,使用方法:

long threadId = tids[0];
long cpuTime = THREAD_MX_BEAN.getThreadCpuTime(threadId);

有谁知道如何(或者如果已知不可能)使用 Sun JVM 获取有关垃圾收集线程的信息?

4

2 回答 2

2

这是特定于 Java 1.5+ Sun (HotSpot) JVM 的。在您要监视的 MBeanServer 中注册 MBean sun.management.HotspotInternal 。这将触发这些 HotSpot 内部 mbean 的注册:

  • sun.management:type=HotspotClassLoading
  • sun.management:type=热点编译
  • sun.management:type=HotspotMemory
  • sun.management:type=HotspotRuntime
  • sun.management:type=热点线程

HotspotThreading MBean 有一个名为 InternalThreadCpuTimes 的属性它是 HotSpot 内部线程的映射。GC 线程可以通过名称来识别例如,在我现在正在运行的 JVM 中,它们被称为:

  • GC 任务线程#1 (ParallelGC)
  • GC 任务线程#0 (ParallelGC)

映射的值是每个线程的 CPU 时间。

HotSpotMemory MBean 还有一个名为 InternalMemoryCounters 的属性其中包含一些关于 GC 的附加信息。

于 2010-11-06T14:06:37.073 回答
1

第一步是使用 verbosegc: java -verbose:gc -XX:+PrintGCDetails,它将为您提供有关 GC 操作中消耗的(挂钟)时间以及操作类型(完整或增量)的一些信息。您的问题似乎是在询问您是否可以通过编程方式获得它——可能可以通过管理 I/F 获得一些信息。

编辑添加:其中一些可通过 MemoryMXBean 获得,但不是 GC 时间的细节。对不起...

于 2010-10-16T02:54:45.050 回答