Java DataInputStream.read() 在被阻塞时导致 20% 的持续 CPU 使用率。
我有一个服务器端应用程序为每个连接的客户端打开一个套接字线程。我在每个线程中有一个 DataInputStream,它调用 read(byte[]array) 来读取数据。我还将套接字超时设置为几分钟。主要代码是这样的:
while (dataInputStream.read(array) != -1) { do something... }
但是,运行几个小时后,在带有 topthreads 插件的 jconsole 中,我可以看到几个客户端线程每个使用 20% 左右的 CPU。如果我单击它,调用堆栈会显示线程在上面的行的 read() 函数上被阻塞。
我知道 read() 函数通常会阻塞等待数据。当阻塞时,它消耗很少的CPU周期。现在,每个线程使用 20% 左右,当更多线程出现相同问题时,我的服务器运行速度越来越慢。我的服务器每秒大约有 5 个连接请求,这种情况很少发生,因为几个小时内只有 5 个线程出现问题。
我真的很困惑。有人可以帮助我吗?
I have a server-side application opens a socket thread for each connected client. I have a DataInputStream in each thread, which calls read(byte[]array) to read data. I also set the socket timeout to a few minutes. The main code is something like this:
while (dataInputStream.read(array) != -1) { do something... }
However, after several hours running, in jconsole with topthreads plugin, I can see several client threads use 20%ish CPU each. If I click on it, the call stack shows the thread is blocked on the above line, on the read() function.
I know read() function will normally block to wait for data. When blocked, it consumes little CPU cycles. Now it's using 20%ish each and my server is running more and more slower when more threads have the same problem. My server has about 5 connection requests per second, and this happens really rarely as in several hours only 5 threads have the problem.
I am really confused. Can someone help me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当 jvm 等待从套接字读取数据时,系统需要不断执行更多活动。
我没有使用确切的技术,但 此链接应该给出一些想法..
为什么不尝试使用
BufferedInputStream
或任何StreamReader
..这些课程将有助于表现。您可以尝试使用 java.util.concurrent 包中的类来改进线程处理(创建线程池将有助于减少消耗的总内存,从而有助于提高整体系统性能)..不确定您是否已经这样做了
when jvm is waiting to read data from a socket there is a lot more activities the system needs to constantly do..
I don't have the exact technique used but this link should give some idea..
why don't you try using a
BufferedInputStream
or any of theStreamReader
s .. these classes would help in the performance.you could try using classes from java.util.concurrent package to improve thread handling (creating a thread pool would help in reducing the total memory consumed, thereby helping in the overall system performance).. not sure if you are doing this already
这段代码无论如何都是错误的。您需要将 read() 的返回值存储在变量中,以便知道返回了多少字节。如果没有这个,应用程序的其余部分就不可能可靠地工作,因此在这个阶段担心时机还为时过早。
然而,除非数组特别小,否则我怀疑您在这里是否真的使用了 20% 的 CPU。更有可能 20% 的已用时间花在了这里。阻塞网络读取不会使用任何 CPU。
This code is wrong anyway. You need to store the return value of read() in a variable so you know how many bytes were returned. The rest of your application can't possibly be working reliably without this anyway, so worrying about timing at this stage is most premature.
However unless the array is exceptionally small, I doubt you are really using 20% CPU in here. More likely 20% of elapsed time is spent here. Blocking on a network read doesn't use any CPU.