有没有办法从 运行 JVM 获得类似 "Dominator Tree" 的功能?

Is there a way to get "Dominator Tree"-like functionality from a running JVM?

最近,我一直在使用 Eclipse MAT. I like it, but the one feature that I seem to use the most is the Dominator Tree 深入研究 JVM 堆转储。 Eclipse 示例截图:

无论如何,我发现很多时候,我通常只看 table 并获得前几个条目就能获得最大价值。因为得到这个的周转时间是:

  1. 创建堆转储(jcmd <pid> GC.heap_dump
  2. Download/Pull heapdump 到一个位置(我们的服务器上没有安装 MAT)
  3. 运行 Eclipse MAT 的 ParseHeapDump.sh 构建各种树的工具
  4. 打开 MAT,单击 支配树 图标。
  5. 分析

有没有办法以编程方式从 运行ning JVM 中获取这些等效信息?我想在主机上 运行 某种 gather_dominators.sh <pid> 脚本并从 JVM 获取前 X 个对象,但我不知道从哪里开始。

如果通过“运行 jvm”你的意思是 - “获取信息而不停止-world heap-dump" 那么显而易见的答案是:为了在没有 "full-scan" 的情况下做这样的事情 - 需要在整个系统生命周期中通过点击每个 creation/release 来收集数据对象并通过维护统计信息。您可以通过检测或使用现成的自定义代理 (jol/jamm/etc) 来实现这些目的。请注意,许多 GC 已经在做类似的工作来收集(和打印)统计信息。 IIRC - 较新的 JVM 甚至在 class- 元数据区域内跟踪此类信息(因此获取统计信息是即时的)。


另一方面 - 如果您可以获取 heap-dump(在任何具有适当节点冗余的生产系统上应该没问题,专为处理不可避免的 Sun-JVM stop-world GC 暂停),然后是 Jhat、MAT-api、YourKit 和 Jol 可能是你最好的朋友:

  • Programmatically analyze java heap dump file
  • How to analyse the heap dump using jmap in java

请务必注意,当前存在的堆转储格式会丢失有关对象实际大小的信息,因此所有工具 (MAT/etc) 都只是 尝试 GUESS 正确:

HTH:)