Почему JMC (JDK Mission Control) не отображает события виртуального потока?

У меня есть небольшое приложение SpringBoot с 1RestControllerследующим методом:

          @GetMapping("/current-thread")
    String currentThread() throws InterruptedException {
        var msg = new Msg();
        Thread.startVirtualThread(() -> {
                    msg.s += Thread.currentThread().toString();
            }
        ).join();
        msg.s += Thread.currentThread().toString();
        return msg.s;
    }

The Msgкласс — это просто строковая оболочка:

          static class Msg{
        String s = new String();
    }

Когда я запускаю приложение и выполняю следующую команду завитка

curl localhost:8081/current-thread

Я получаю этот вывод:

VirtualThread[#63]/runnable@ForkJoinPool-1-worker-1Thread[#38,http-nio-8081-exec-1,5,main]

Это означает, что приложение работает нормально. При каждом запросе создается виртуальный поток.

Но когда я отслеживаю это через JFR (JDK Flight Recorder) и проверяю запись через JMC (Java Mission Control), я вижу потоки платформы, а именно:http-nioиForkJoinPool-workerпотоки. Но никаких следов виртуального потока я не вижу. Он не отображает никаких событий, связанных с виртуальными потоками: в JMC нет событий виртуальных потоков.Я ожидал, что он покажет 1 событие VirtualThreadstart и 1 событие VirtualThreadEnd. Я попробовал собрать JMC локально из исходного кода. Но я вижу ту же проблему.

Мои вопросы:

  • Есть ли что-то, чего мне не хватает?
  • Эта функция не работает в JMC? (Я использовал JMC 8.3.1, а также локально собрал версию 9.0 из исходного кода.)
  • Есть ли обходной путь?

Спасибо.

1 ответ

Виртуальные потоки по-прежнему являются функцией предварительной версии в JDK 20, что означает, что события, специфичные для виртуальных потоков, являются экспериментальными и по умолчанию не отображаются в графическом интерфейсе JMC.

Кроме того, некоторые события, специфичные для виртуальных потоков, такие как начало виртуального потока и завершение виртуального потока, по умолчанию отключены, чтобы избежать переполнения буферов. Пользователь потенциально может запустить миллионы виртуальных потоков за короткий период времени.

Вы можете загрузить сборки раннего доступа JDK 21 , в которых события уже не являются экспериментальными, и включить их из командной строки:

      $ java -XX:StartFlightRecording:
    jdk.VirtualThreadStart#enabled=true,
    jdk.VirtualThreadEnd#enabled=true,
    filename=recording.jfr ...

События, происходящие в виртуальном потоке, например событие чтения сокета, должны просматриваться без дополнительных опций, при условии, что продолжительность превышает 20 мс (порог по умолчанию). Однако они не будут отображаться на странице «График потоков» в JMC. Он отображает только потоки платформы.

Другие вопросы по тегам