BLOCKED 线程会导致高 CPU 消耗吗
Can a BLOCKED Thread cause high CPU Consumption
我们最近在生产环境中发现了一个高 CPU 消耗问题,并且在调试时看到了一些奇怪的东西。当我执行 "top -H" 查看每个线程 ID 的 CPU 统计信息时,我发现一个线程 X 消耗很高 CPU。当我进行线程转储时,我看到这个线程 X 处于 BLOCKED 状态。这是什么意思,处于 BLOCKED 状态的线程可以消耗 high CPU 吗?我认为这可能是一个微不足道的问题,但我是调试性能问题和 JVM 的新手,不确定我在这里可能遗漏了什么。
进入和退出 BLOCKED 状态可能代价高昂。如果您被阻塞了一小会儿,这不是问题,但如果您在繁忙的循环中短暂阻塞,您的线程可能看起来被阻塞,但实际上正在燃烧 CPU.
我会寻找多个线程重复竞争共享资源,这些资源非常短暂地进入 BLOCKED。
@Peter 已经提到了关于忙循环的好处(在同步的情况下可能是 JVM 内部 adaptive optimization 的自旋锁,或者在某些情况下由应用程序本身创建的忙循环)可以燃烧 CPU.还有另一种 间接 方式,其中 CPU 可以由于线程阻塞而变得非常高。通常在 Web 服务器中,如果许多线程处于阻塞状态(不是因为与同步锁相关的阻塞,而是说等待来自后端数据存储的 IO),那么它可能会给 JVM 垃圾收集带来很大压力。这些工作线程应该快速完成它们的工作,以便它们在堆上创建的所有对象都被快速取消引用并被垃圾收集。如果很多线程处于这种状态,那么垃圾收集线程必须加班工作,它们最终可能会占用大量 CPU.
我们最近在生产环境中发现了一个高 CPU 消耗问题,并且在调试时看到了一些奇怪的东西。当我执行 "top -H" 查看每个线程 ID 的 CPU 统计信息时,我发现一个线程 X 消耗很高 CPU。当我进行线程转储时,我看到这个线程 X 处于 BLOCKED 状态。这是什么意思,处于 BLOCKED 状态的线程可以消耗 high CPU 吗?我认为这可能是一个微不足道的问题,但我是调试性能问题和 JVM 的新手,不确定我在这里可能遗漏了什么。
进入和退出 BLOCKED 状态可能代价高昂。如果您被阻塞了一小会儿,这不是问题,但如果您在繁忙的循环中短暂阻塞,您的线程可能看起来被阻塞,但实际上正在燃烧 CPU.
我会寻找多个线程重复竞争共享资源,这些资源非常短暂地进入 BLOCKED。
@Peter 已经提到了关于忙循环的好处(在同步的情况下可能是 JVM 内部 adaptive optimization 的自旋锁,或者在某些情况下由应用程序本身创建的忙循环)可以燃烧 CPU.还有另一种 间接 方式,其中 CPU 可以由于线程阻塞而变得非常高。通常在 Web 服务器中,如果许多线程处于阻塞状态(不是因为与同步锁相关的阻塞,而是说等待来自后端数据存储的 IO),那么它可能会给 JVM 垃圾收集带来很大压力。这些工作线程应该快速完成它们的工作,以便它们在堆上创建的所有对象都被快速取消引用并被垃圾收集。如果很多线程处于这种状态,那么垃圾收集线程必须加班工作,它们最终可能会占用大量 CPU.