Я предполагаю, что вы передаете слишком маленькое значение в 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 (), который прекрасно выполняет свою работу - но когда он завершается, он становится одним из самых продолжительных методов в моем приложении -несколько раз.

Ответы на вопрос(4)

Ваш ответ на вопрос