Я предполагаю, что вы передаете слишком маленькое значение в fib, и программа просто не запускается достаточно долго для регистрации. Чтобы получить значимые данные для чего-либо практически во время профилирования (или оценки производительности), вам обычно требуется затраченное время, по крайней мере, несколько секунд.
исал этот небольшой (и крайне неэффективный) класс и хотел профилировать его с помощью Java VisualVM.
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
int n = Integer.parseInt(args[0]);
int fib = fib(n);
System.out.println(fib);
}
private static int fib(int n) {
if (n < 2) {
return n;
}
return fib(n-1)+fib(n-2);
}
}
Результаты странные. В результатах полностью преобладают вызовы ConnectionHandler.run ().
(98,2%) sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run ()
(1,7%) java.lang.Thread.join (длинный)
(0%) java.lang.String.equals (Объект)
и т.д...
Существует около ста профилированных методов, и ни один из них не является fib (int)!
Невероятно, что моя программа на самом деле тратит все свое время на эти методы. Похоже, они подключаются к моему jvm и делают свое дело.
Что я делаю неправильно?
Отредактировано для ясности: Если вы передадите 45 для этого приложения, это приложение будет работать в течение 20 секунд с хорошими профилями. Изначально программа, которую я профилировал (не калькулятор Фибоначчи), привязывает все четыре ядра к моему процессору на 100%, и я выполнял профилирование продолжительностью до 5 минут. У них были те же самые результаты, и методы из моего приложения не появлялись в списке горячих точек.
Это варьируется от запуска к запуску, но ConnectionHandler.run () всегда находится наверху и обычно составляет ~ 99% времени профиля.
Второе редактирование: Я попытался использовать сэмплер, и теперь я получаю результаты, которые соответствуют тому, что производит JProfiler. Недостатком этого является то, что я не получаю информацию трассировки стека, которая поставляется с профилированием. Но для моих насущных потребностей это отлично.
Что-то, что я обнаружил во время игры, - это то, что VisualVM считает часы настенного времени для вызовов методов при их профилировании.
В моем конкретном случае мое приложение имеет основной поток, который запускает рабочие потоки и немедленно блокирует ожидание сообщения в очереди.
Это означает, что метод блокировки, по-видимому, занимает почти все время на профилировщике, несмотря на тот факт, что не этот метод поглощает мой процессор.
Я ожидаю, что то же самое относится и к методу sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run (), который прекрасно выполняет свою работу - но когда он завершается, он становится одним из самых продолжительных методов в моем приложении -несколько раз.