问题描述
如何(从Java应用程序/代理中)以编程方式(在Java应用程序/代理中)获得实时"广告?堆中最大对象的摘要(包括其实例数和大小)?
How programmatically (from within the java application/agent) do I get a "live" summary of the largest objects in the heap (including their instances count and size)?
类似于探查器的工作.
例如,这是JProfiler的屏幕截图:
For example, here is a screenshot from JProfiler:
通常,在我确实需要堆转储的情况下,我经常使用堆转储,但是现在我想弄清楚分析器如何从运行的JVM中准确地检索此类信息,而无需实际进行堆转储.
Usually I used to work with heap dumps in the cases where I really needed that, but now I would like to figure out how exactly profilers retrieve this kind of information from the running JVM without actually taking a heap dump.
是否可以通过使用Java API获得此类信息?如果不可能,那么本机代码中的替代方法是什么?代码示例将是最适合我的需求的代码,因为Java Universe的这一特定部分对我来说真的很新.
Is it possible to get this kind of information by using the Java API? If its impossible what is the alternative in the native code? Code example would be the best for my needs, because this specific part of java universe is really new to me.
我有点相信,如果我有兴趣查找有关某些特定类的信息,我可以使用工具或其他方法,但是据我所知,这里使用了采样,因此应该有另一种方法.
I kind of believe that if I was interested to find the information about some really specific classes I could use instrumentation or something, but here as far as I understand, it uses the sampling so there should be another way.
我目前正在使用在Linux上运行Java 8的HotSpot VM,但是通用"的功能却更多.我会找到解决方案-更好.
I'm currently using HotSpot VM running java 8 on linux, however the more "generic" solution I'll find - the better.
推荐答案
没有用于堆漫游的标准Java API.但是,可以通过JMX调用特定于HotSpot的诊断命令:
There is no standard Java API for heap walking. However, there is a HotSpot-specific diagnostic command that can be invoked through JMX:
String histogram = (String) ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),
"gcClassHistogram",
new Object[]{null},
new String[]{"[Ljava.lang.String;"});
这将收集类直方图,并以单个格式化的 String
返回结果:
This will collect the class histogram and return the result as a single formatted 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
命令的输出.
The contents is equivalent to the output of jmap -histo
command.
唯一用于堆漫游的标准 API是本机JVM TI IterateThroughHeap
函数,但使用起来并不容易,并且比上述诊断命令要慢得多.
The only standard API for heap walking is the native JVM TI IterateThroughHeap
function, but it's not so easy to use, and it works much slower than the above diagnostic command.
这篇关于JVM以编程方式获取堆中最大的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!