java - JVM 以编程方式获取堆中最大的对象
问题描述
如何以编程方式(从 java 应用程序/代理中)获得堆中最大对象的“实时”摘要(包括它们的实例数和大小)?
与 Profilers 所做的类似。
例如,下面是 JProfiler 的截图:
通常我曾经在我真正需要的情况下使用堆转储,但现在我想弄清楚探查器如何从正在运行的 JVM 中准确地检索到这种信息,而无需实际进行堆转储。
是否可以通过使用 Java API 获取此类信息?如果不可能,本机代码中的替代方案是什么?代码示例最适合我的需要,因为 java 世界的这个特定部分对我来说真的很新。
我有点相信,如果我有兴趣找到一些真正具体的类的信息,我可以使用仪器或其他东西,但据我所知,它使用采样,所以应该有另一种方式。
我目前正在使用在 linux 上运行 java 8 的 HotSpot VM,但是我会找到更“通用”的解决方案 - 更好。
解决方案
没有用于堆遍历的标准 Java API。但是,有一个特定于 HotSpot 的诊断命令可以通过 JMX 调用:
String histogram = (String) ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),
"gcClassHistogram",
new Object[]{null},
new String[]{"[Ljava.lang.String;"});
这将收集类直方图并以单一格式返回结果String
:
num #instances #bytes class name
----------------------------------------------
1: 3269 265080 [C
2: 1052 119160 java.lang.Class
3: 156 92456 [B
4: 3247 77928 java.lang.String
5: 1150 54104 [Ljava.lang.Object;
6: 579 50952 java.lang.reflect.Method
7: 292 21024 java.lang.reflect.Field
8: 395 12640 java.util.HashMap$Node
...
内容相当于jmap -histo
命令的输出。
堆遍历的唯一标准API 是本机 JVM TIIterateThroughHeap
函数,但它并不那么容易使用,而且它的工作速度比上面的诊断命令慢得多。
推荐阅读
- javascript - 选择日期时如何更新 datetimepicker?
- android - Android Studio 中不再显示单选按钮
- java - 如何在遍历 sql 数据库之前从 rs.next() 中获取值?
- python - 为什么 pd.Series 被调用两次?
- php - @nbsp 不适用于 php 数据库值
- ios - ITMS-90809:不推荐使用的 API 使用 (UIWebView)
- sql - 仅当达到 Max Date 时才更新 SQL
- python - 排序方法的Python字母顺序显示错误的顺序
- r - ggplot - 制作自定义地图
- html - 如何将视频转换为 html5 动画或幻灯片