在分析国产web应用程序时,我发现了非常奇怪的观察(至少对我来说是这样)。
几乎所有的时间都花在SocketInputStream类的SocketInputStream方法上。这并不奇怪,因为我的应用程序在每个请求上都使用远程服务进行网络连接。奇怪的是,对于这种方法来说,不仅墙壁时钟使用率高,CPU时钟时间也很高。我不明白为什么CPU时间很长,因为如果我的应用程序等待远程服务回复(实际上并不是这么快),那么应用程序本身就没有什么可做的了。所以CPU的时间应该很低。
一些更多的意见:
SocketInputStream.socketRead0()方法消耗了95%的时间(壁时钟时间和 CPU时间);mpstat (我们使用Linux作为操作系统)显示了大约90%的用户时间和1%-3%的系统时间(其余是空闲时间);RestTemplate与远程服务交互,而不是直接与SocketInputStream交互。现在我只有一个想法--也许这是在JVM中调用本机方法的开销(SocketInputStream.socketRead0()是本机的)?
你认为如何?这还有什么别的原因吗?
发布于 2017-04-26 06:00:04
我也面临着同样的问题。我的应用程序有一个非常高的qps,每个请求都会使我发送多个节省调用,这些调用使用本机api:socketRead0。
所以我决定做个实验。在返回之前,我使用api来制作一个模拟服务器,30度睡眠,客户端调用这个api。我的目的是在net发生时测试线程状态。基于我的线程转储,线程状态是RUNNABLE。
这就解释了两件事:
RUNNABLE,这将有助于高用户空间cpu利用率。这两个都将使您的cpu繁忙。
我注意到在实验中,系统空间cpu利用率很低。我认为这与jvm和os之间的线程调度策略不同有关。我们知道热点线程模型是1:1,这意味着一个jvm线程到一个os线程。当发生阻塞io (如socketRead0 )时,内核线程将设置为状态S,而不会阻塞cpu,但是用户空间线程正在阻塞(等待)。当发生这种情况时,我认为我们需要重新考虑应用程序中的基本I/O模型。
发布于 2013-08-01 02:27:09
VisualVM显示的不是一个绝对值,而是一个相对值,所以它只是意味着您的应用程序没有更多的CPU消耗点。
我认为您应该将VisualVM配置为不深入挖掘,而是将此方法调用作为代码(或spring的)中的方法的一部分来计算。
我已经经历过这样的行为,但看起来不需要任何优化。Web应用程序只需从套接字读取数据(即HTTP请求、数据库、内部网络服务.)也帮不上忙。
https://stackoverflow.com/questions/12489215
复制相似问题