我对使用JFR程序进行性能分析时是否有可能以纳秒为单位获取每个或大多数用户方法的开始和结束时间?
我知道可以使用代码检测,但我想利用采样分析器的优势来减少对实际程序执行的影响。
我有一种感觉,它应该是可能的,因为我认为JFR需要此信息进行热方法百分比评估,但不知道如何获得该时间。 有人可以帮忙吗?
答案 0 :(得分:1)
使用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);
}