4

我们最近在生产环境中看到了 CPU 消耗高的问题,并且在调试时发现了一些奇怪的问题。当我执行“top -H”来查看每个线程 ID 的 CPU 统计信息时,我发现一个线程 X 消耗了高 CPU。当我进行线程转储时,我看到这个线程 X 处于 BLOCKED 状态。这是什么意思,处于 BLOCKED 状态的线程可以消耗高 CPU 吗?我认为这可能是一个微不足道的问题,但我是调试性能问题和 JVM 的新手,不确定我可能在这里遗漏了什么。

4

2 回答 2

6

进入和退出 BLOCKED 状态可能会很昂贵。如果您被阻塞了一小会儿,这不是问题,但如果您在繁忙的循环中短暂阻塞,您的线程可能看起来被阻塞,但实际上正在消耗 CPU。

我会寻找多个线程反复竞争共享资源,这些资源非常短暂地进入 BLOCKED。

于 2017-03-09T12:13:31.643 回答
3

@Peter 已经提到了关于繁忙循环的好点(这可能是 JVM 在同步的情况下对自旋锁的内部自适应优化或应用程序本身在某些情况下创建的繁忙循环),这可能会消耗 CPU。还有一个间接的由于线程阻塞,CPU 可能会变得非常高的方式。通常在 Web 服务器中,如果许多线程处于阻塞状态(不是因为与同步锁相关的阻塞,而是说等待来自后端数据存储的 IO),那么它可能会给 JVM 垃圾收集带来很大压力。这些工作线程应该快速完成它们的工作,以便它们在堆上创建的所有对象都被快速取消引用并收集垃圾。如果很多线程都处于这种状态,那么垃圾收集线程必须超时工作,最终可能会占用大量 CPU。

于 2017-08-12T04:57:00.140 回答