找出所有发生阻塞操作的java代码位置

Dav*_*ann 1 java jvm asynchronous netty

在我们的Netty应用程序中。我们正在将代码中的所有阻塞调用移至特殊的backgroundThreadGroup.

我希望能够登录生产环境threadNamelineNumber即将执行阻塞操作的java代码。(即同步文件和网络IO)

这样我就可以 grep 查找日志,查看我们可能错过了将阻止代码移动到backgroundThreadGroup.

有没有一种方法可以检测 JVM,以便它可以告诉我这一点?

apa*_*gin 5

取决于“阻止操作”的含义。

从广义上讲,任何导致自愿上下文切换的操作都是阻塞的。试图对它们做一些特别的事情是绝对不切实际的。

例如,在 Java 中,任何包含的方法都synchronized可能是阻塞的。这包括

  • ConcurrentHashMap.put
  • SecureRandom.nextInt
  • System.getProperty

还有很多。我不认为您真的想避免调用所有这些乍一看看起来很正常的方法。

即使没有任何同步原语的简单方法也可能会阻塞。例如,ByteBuffer.get可能会导致操作系统级别的页面错误和阻塞读取。此外,正如评论中提到的,有些 JVM 级别的阻塞操作不受您的控制。

简而言之,在代码中找到发生阻塞操作的所有位置,即使不是不可能,也是不切实际的。

但是,如果您有兴趣查找您认为不好的特定方法调用(例如Thread.sleepSocket.read),那么您绝对可以这样做。有一个BlockHound项目专门用于此目的。它已经有一个预定义的“坏”方法列表,但可以使用您自己的列表进行自定义。