IntelliJ IDEA 2025.2 Help

线程转储

线程转储是一种用于检查应用程序在特定时刻状态的工具。 它们提供应用程序中线程的列表及其堆栈轨迹,这对于调试诸如死锁或无响应的 UI 等问题非常有用。 线程转储的主要优势在于其纯文本格式以及众多的工具可以捕获并处理它们。

IntelliJ IDEA 允许您捕获正在运行进程的线程转储,并解释在 IntelliJ IDEA 或其他工具(例如 jstack jcmd )中获取的外部线程转储。

IntelliJ IDEA 支持由 JDK 工具生成的最高至版本 24 的格式。

从 IntelliJ IDEA 捕获线程转储

  1. 从 IntelliJ IDEA 运行程序时:在 运行 工具窗口的工具栏中,点击 转储线程

    运行工具窗口工具栏中的“转储线程”按钮
  2. 从 IntelliJ IDEA 调试程序时:在 调试 工具窗口的工具栏中,点击 更多更多 ,然后选择 获取线程转储

    调试工具窗口工具栏中的“更多”按钮
  3. 对于本地运行的任何 Java/Kotlin 进程:在 首页 工具窗口的 分析器 选项卡中,点击您希望为其创建线程转储的进程。 选择 获取线程转储

    右键点击 Profiler 工具窗口中的进程时,会打开一个菜单

打开外部线程转储

  1. 在主菜单中,前往 代码 | 分析堆栈跟踪或线程转储

  2. 在打开的 分析堆栈跟踪 对话框中,将线程转储粘贴到 请在此处放置堆栈跟踪或完整的线程转储: 文本区域。

线程转储会在一个新的工具窗口选项卡中打开。 此视图是可自定义的:您可以应用筛选和排序,合并相似的线程,并部分折叠堆栈跟踪。

线程名称旁边的图标表示线程的状态:

图标

描述

运行/活跃 — 默认状态,线程正在主动执行代码。

(用于 Kotlin 协程)运行 — 协程正在主动执行代码。

休眠 — 发生在线程处于 Thread.sleep 状态时,或在其处于停顿或等待条件时。

承载线程 — 当前执行虚拟线程的平台线程,或处于 已创建/未知 状态的协程。

等待 — 线程正在等待对象监视器,或协程已挂起时发生。

套接字 — 线程正在执行网络 I/O 操作时发生。

I/O — 线程正在执行非网络 I/O 操作时发生。

EDT(事件分发线程)— Swing 应用中的 UI 线程。 表示空闲的 EDT, 表示活跃的。

此外,波浪覆盖图表示虚拟线程和 Kotlin 协程,而“幽灵”覆盖图表示守护线程:

线程转储中的覆盖图,指示虚拟线程和守护线程

运行 工具窗口中的某些调用具有虚线下划线。 这些调用发生在 try 块中,并可能抛出已检查异常。

如果您想检查出现在堆栈跟踪中的类,您可以直接从线程转储导航到它。

跳转到源

  • 点击堆栈跟踪中的超链接。

    线程转储中的超链接

如果您想保存线程转储以供以后检查或发送给其他人,您可以将其导出为文本文件。

将线程转储导出为文本文件

  1. 在工具栏中点击 导出到文本文件

    线程转储查看器中的“导出到文本文件”按钮
  2. 指定路径并点击 保存

IntelliJ IDEA 的线程转储格式

在以文本格式查看 IntelliJ IDEA 的线程转储时,您可能会注意到线程描述和堆栈轨迹中附加的信息。

它看起来如下所示:

"main" prio=5 tid=0x000001f3c9d13000 nid=NA runnable java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) - locked <0x00000007ab1d3fa8> (a java.io.InputStreamReader) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)

每个线程在转储中包括以下信息:

线程头行

"Thread-Name" [state flags] prio=N tid=0xHEXVALUE nid=NA [thread state]

每个线程描述的第一行为线程头行,包含以下部分:

  • 用引号括起来的线程名称

  • 可选标志,指示线程是守护线程或虚拟线程

  • 线程优先级(prio)– 由 JVM 管理的值,表示线程的调度优先级,范围从 1(最低)到 10(最高)。 默认值为 5。 这些优先级可能映射到操作系统级线程优先级,但映射取决于实现,优先级仅用作调度程序的提示,而不是执行顺序的保证。

  • 线程 ID(十六进制)(tid

  • 本地 ID(nid)– 通常在 IDE 生成的转储中为 NA。 该信息通常仅在由 JVM 本身生成线程转储时可用

  • 线程状态。 可识别以下状态:

    线程状态

    描述

    runnable

    线程正在运行或准备运行

    sleeping

    线程处于休眠状态(Thread.sleep()

    waiting on condition

    线程正在等待某个条件

    waiting for monitor entry

    线程正在等待获取监视器锁

    sleeping

    线程处于休眠状态(Thread.sleep()

    parking

    线程已挂起(LockSupport.park()

    on object monitor

    线程正在对象监视器上等待

    idle

    事件分发线程处于空闲状态

线程状态行

线程状态行紧跟在线程头行之后,包含 JVM 指示的线程状态。 可能的状态如下:

线程状态

描述

NEW

尚未开始执行的线程

RUNNABLE

在 Java 虚拟机中执行的线程

BLOCKED

被阻塞的线程,正在等待监视器锁

WAITING

无限期等待另一个线程执行某个操作的线程

TIMED_WAITING

等待另一个线程在指定时间内执行操作的线程

TERMINATED

已完成执行的线程

有关线程状态的更多信息,请参阅 官方 Java 文档

堆栈跟踪

堆栈轨迹显示线程的方法调用顺序,其特征如下:

  • 堆栈轨迹中的每一行都以制表符开始。

  • 方法调用从顶部(最近/被调用方法)列至底部(较早/调用方法)。

  • 每行遵循以下格式: at package.class.method(SourceFile:LineNumber)。 当 IntelliJ IDEA 识别出源文件时,您可以使用它 跳转到源代码

锁信息

当可用时,IntelliJ IDEA 的线程转储会提供线程持有锁的信息,包括:

  • 该线程拥有的监视器

  • 被该线程阻塞的线程

  • 该线程正在等待的监视器

  • 带有其类和内存地址的锁对象

Kotlin 协程

您可以在 IntelliJ IDEA 的线程转储中查看 Kotlin 协程以及 Java 线程。 例如:

"coroutine:2" SUSPENDED at kotlinx.coroutines.DelayKt.awaitCancellation(Delay.kt:157) at NetworkServiceKt.fetchData(NetworkService.kt:15) at MainKt$main$1.invokeSuspend(Main.kt:11) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)

协程信息的格式如下:

"CoroutineName:id" (state) [dispatcher] <coroutine descriptor> <stack trace>
  • 名称和 ID:协程名称后跟其唯一 ID,例如 coroutine:1

  • 状态:协程的当前状态,例如 暂停

  • 调度器:关于协程使用的调度器的信息,例如 Dispatchers.IO

  • 堆栈跟踪:协程的堆栈帧

协程可以处于以下状态之一:

协程状态

描述

运行中

协程当前正在执行

暂停

协程在挂起点被挂起

创建

协程已创建但尚未启动

未知

无法确定状态

最后修改日期: 2025年 9月 22日