SocketInputStream.socketRead0()中CPU使用率高的原因

Den*_*nov 17 java linux performance jvm cpu-usage

在剖析本土网络应用程序时,我遇到了非常奇怪的(至少对我来说)观察.

几乎所有的时间都花在socketRead0()SocketInputStream课堂的方法上.这并不奇怪,因为我的应用程序在每个请求上都使用远程服务进行联网.奇怪的是,这种方法不仅挂钟时间使用率高,而且CPU时钟时间也很高.我无法理解为什么CPU时间很长,因为如果我的应用程序等待远程服务回复(实际上并不是那么快),那么应用程序本身就没有什么可做的了.所以CPU时间应该很低.

更多观察:

  • 采样模式下的VisualVM显示该方法SocketInputStream.socketRead0()占用时间高达95%(挂钟时间 CPU时间);
  • mpstat (我们使用Linux作为操作系统)显示约90%的用户时间和约1-3%的系统时间(其余为空闲时间);
  • 应用程序部署在专用服务器上;
  • 远程服务也是HTTP Web应用程序.平均响应时间约为100毫秒.平均响应大小约为2Kb.
  • 我的应用程序使用spring RestTemplate来与远程服务进行交互,而不是SocketInputStream直接进行.

现在我只有一个想法 - 也许这是在JVM中调用本机方法的开销(SocketInputStream.socketRead0()原生)?

你怎么看?还有其他原因吗?

mau*_*hiz 0

VisualVM 将负载显示为相对值而不是绝对值,因此这仅意味着您的应用程序不再有任何 CPU 消耗点。

我相信您应该将 VisualVM 配置为不深入钻取,而是将此方法调用视为您的代码(或 spring 的)中方法的一部分。

我已经经历过这样的行为,但看起来不需要任何优化。Web 应用程序只需从套接字读取数据(即 HTTP 请求、数据库、内部网络服务...),对此没有任何帮助。