Java 使用 jcmd 命令查看虚拟线程堆栈信息
Java juc jcmd About 6,348 wordsThread.dump_to_file
jcmd中的Thread相关命令有Thread.print和Thread.dump_to_file(还有Thread.vthread相关命令)。
Thread.print中不能查看虚拟线程相关命令,需使用Thread.dump_to_file将线程信息导出到文件后查看。
PS \openjdk-25> jcmd 20308 help Thread.dump_to_file
20308:
Thread.dump_to_file
Dump threads, with stack traces, to a file in plain text or JSON format.
Impact: Medium: Depends on the number of threads.
Syntax : Thread.dump_to_file [options] <filepath>
Arguments:
filepath : The file path to the output file (FILE, no default value)
Options: (options must be specified using the <key> or <key>=<value> syntax)
-overwrite : [optional] May overwrite existing file (BOOLEAN, false)
-format : [optional] Output format ("plain" or "json") (STRING, plain)
format
Thread.dump_to_file可以使用-format参数指定导出后文件的格式。
overwrite
是否覆盖已存在的文件。
使用
jcmd <pid> Thread.dump_to_file -format=json ~/thread.json
堆栈信息
虚拟线程会有virtual: true的标识。
{
"threadDump": {
"processId": "14244",
"time": "2025-10-10T07:39:23.174417600Z",
"runtimeVersion": "25+36-3489",
"threadContainers": [
{
"container": "<root>",
"parent": null,
"owner": null,
"threads": [
{
"tid": "3",
"time": "2025-10-10T07:39:23.187416900Z",
"name": "main",
"state": "TIMED_WAITING",
"parkBlocker": {
"object": "java.util.concurrent.CountDownLatch$Sync@3df72b07"
},
"stack": [
"java.base\/jdk.internal.misc.Unsafe.park(Native Method)",
"java.base\/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:271)",
"java.base\/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:792)",
"java.base\/java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1166)",
"java.base\/java.util.concurrent.CountDownLatch.await(CountDownLatch.java:276)",
"java.base\/java.util.concurrent.ThreadPerTaskExecutor.awaitTermination(ThreadPerTaskExecutor.java:159)",
"java.base\/java.util.concurrent.ThreadPerTaskExecutor.awaitTermination(ThreadPerTaskExecutor.java:173)",
"java.base\/java.util.concurrent.ThreadPerTaskExecutor.close(ThreadPerTaskExecutor.java:189)",
"com.center.FJPMain.main(FJPMain.java:18)"
]
},
{
"tid": "25",
"time": "2025-10-10T07:39:23.198423300Z",
"name": "VirtualThread-unblocker",
"state": "RUNNABLE",
"stack": [
"java.base\/java.lang.VirtualThread.takeVirtualThreadListToUnblock(Native Method)",
"java.base\/java.lang.VirtualThread.unblockVirtualThreads(VirtualThread.java:1507)",
"java.base\/java.lang.Thread.run(Thread.java:1474)",
"java.base\/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:148)"
]
},
{
"tid": "80",
"time": "2025-10-10T07:39:23.199417200Z",
"name": "Read-Poller",
"state": "RUNNABLE",
"stack": [
"java.base\/sun.nio.ch.WEPoll.wait(Native Method)",
"java.base\/sun.nio.ch.WEPollPoller.poll(WEPollPoller.java:61)",
"java.base\/sun.nio.ch.Poller.pollerLoop(Poller.java:248)",
"java.base\/java.lang.Thread.run(Thread.java:1474)",
"java.base\/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:148)"
]
},
{
"tid": "81",
"time": "2025-10-10T07:39:23.199417200Z",
"name": "Write-Poller",
"state": "RUNNABLE",
"stack": [
"java.base\/sun.nio.ch.WEPoll.wait(Native Method)",
"java.base\/sun.nio.ch.WEPollPoller.poll(WEPollPoller.java:61)",
"java.base\/sun.nio.ch.Poller.pollerLoop(Poller.java:248)",
"java.base\/java.lang.Thread.run(Thread.java:1474)",
"java.base\/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:148)"
]
},
...
],
"threadCount": "11"
},
{
"container": "ForkJoinPool.commonPool\/jdk.internal.vm.SharedThreadContainer@625d8625",
"parent": "<root>",
"owner": null,
"threads": [
],
"threadCount": "0"
},
{
"container": "java.util.concurrent.ThreadPoolExecutor@2c42d3fb",
"parent": "<root>",
"owner": null,
"threads": [
],
"threadCount": "0"
},
{
"container": "ForkJoinPool-1\/jdk.internal.vm.SharedThreadContainer@5c8e12cf",
"parent": "<root>",
"owner": null,
"threads": [
],
"threadCount": "0"
},
{
"container": "java.util.concurrent.ThreadPerTaskExecutor@3bb940ce",
"parent": "<root>",
"owner": null,
"threads": [
{
"tid": "26",
"time": "2025-10-10T07:39:23.207418700Z",
"virtual": true,
"name": "",
"state": "WAITING",
"stack": [
"java.base\/java.lang.VirtualThread.park(VirtualThread.java:738)",
"java.base\/java.lang.System$1.parkVirtualThread(System.java:2284)",
"java.base\/java.util.concurrent.locks.LockSupport.park(LockSupport.java:367)",
"com.center.FJPMain.lambda$main$0(FJPMain.java:15)",
"java.base\/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)",
"java.base\/java.util.concurrent.FutureTask.run(FutureTask.java:328)",
"java.base\/java.util.concurrent.ThreadPerTaskExecutor$ThreadBoundFuture.run(ThreadPerTaskExecutor.java:323)",
"java.base\/java.lang.VirtualThread.run(VirtualThread.java:456)"
]
}
],
"threadCount": "1"
}
]
}
}
测试代码
public class TestMain {
public static void main(String[] args) throws Throwable {
try (ExecutorService executorService = Executors.newThreadPerTaskExecutor(Thread.ofVirtual().factory())) {
executorService.submit(() -> {
LockSupport.park();
});
}
}
}
Views: 14 · Posted: 2025-12-27
———         Thanks for Reading         ———
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...