我感兴趣的是,在使用 JFR 程序进行分析时,是否可以为每个或大多数用户方法获取以纳秒为单位的开始和结束时间?
我知道可以使用代码检测,但我想利用采样分析器的优势来减少对实际程序执行的影响。
我有一种感觉应该是可能的,因为我相信 JFR 需要此信息来进行热方法百分比评估,但不知道如何获得那个时间。有人可以帮忙吗?
使用 JFR 是不可能的。
由于它是一个采样分析器,它只会收集采样时堆栈顶部的方法。您可以在它发生时获得高精度的时间戳,但它不会告诉您该方法执行了多长时间。
这是一个显示如何构建直方图的程序。
try (RecordingFile f = new RecordingFile(Paths.get("recording.jfr"))) {
Map<String, SimpleEntry<String, Integer>> histogram = new HashMap<>();
int total = 0;
while (f.hasMoreEvents()) {
RecordedEvent event = f.readEvent();
if (event.getEventType().getName().endsWith(".ExecutionSample")) {
RecordedStackTrace s = event.getStackTrace();
if (s != null) {
RecordedFrame topFrame= s.getFrames().get(0);
if (topFrame.isJavaFrame()) {
RecordedMethod method = topFrame.getMethod();
String methodName = method.getType().getName() + "#" + method.getName() + " " + method.getDescriptor();
Entry entry = histogram.computeIfAbsent(methodName, u -> new SimpleEntry<String, Integer>(methodName, 0));
entry.setValue(entry.getValue() + 1);
total++;
}
}
}
}
List<SimpleEntry<String, Integer>> entries = new ArrayList<>(histogram.values());
entries.sort((u, v) -> v.getValue().compareTo(u.getValue()));
for (SimpleEntry<String, Integer> c : entries) {
System.out.printf("%2.0f%% %s\n", 100 * (float) c.getValue() / total, c.getKey());
}
System.out.println("\nSample count: " + total);
}