Почему 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. Он отображает только потоки платформы.