Ubuntu 12.04 LTS
java -version
java版本“1.6.0_38”
Java(TM)SE运行时环境(build 1.6.0_38-b05)
Java HotSpot(TM)64位服务器虚拟机(构build20.13-b02,混合模式)
4核心CPU – 一些戴尔服务器硬件
不时有10个线程在数分钟内运行一个“繁重”的工作。 在其他时期,他们什么都不做。
1线程应该每5秒钟左右唤醒一次,然后通过networking发送一个快速ping到另一个进程。 这很好地工作,只要其他10个线程什么也不做,但是当其他10个线程运行一个“繁重”的工作时,它永远不会(或很less)运行并发送它的ping。
如果这个“繁重”的工作是CPU密集型的,我可以理解这一点。 但在这样一个“繁重”的工作顶部说50-100%IO等待,但约1%的CPU使用率。 分析表明,在一些NIO调用中,大部分时间花费在10个线程中(等待着我猜)。 这一切都加起来,并且有点期待,因为有关工作的沉重感是从磁盘读取文件。
我不明白的是,在这样一个“沉重”的工作中,做ping的1个线程不能运行。 当顶部显示1%的CPU使用率时,怎么能解释这个问题?看起来10个线程花费了大部分时间来等待IO。 当其他线程正在等待IO时,1个ping线程是否应该获得执行时间?
Java线程优先级在所有11个线程上是相等的。
在这10个线程中传播几个yield,似乎可以解决(或降低)这个问题,但我不明白为什么ping线程不能在没有收益的情况下运行,而其他线程没有太多的工作,为IO。
其他信息05.03.2014
我已经在一个更简单的设置中重现了这个问题 – 尽pipe不是很简单(但是您将不得不找出如何安装Apache Zookeeper服务器,但是相当简单 – 稍后我可以提供信息)
在这里findEclipse Kepler项目(maven – 由“mvn package”构build): https : //dl.dropboxusercontent.com/u/25718039/io-test.zip
在这里find二进制文件: https : //dl.dropboxusercontent.com/u/25718039/io-test-1.0-SNAPSHOT-jar-with-dependencies.jar
在机器上启动Apache ZooKeeper 3.4.5(端口2181)服务器。 在另一台单独的机器上(这是我上面所述的Ubuntu 12.04 LTS等)运行二进制文件如下(首先创build一个文件夹io-test-files – 需要50GB的空间)
nohup java -cp io-test-1.0-SNAPSHOT-jar-with-dependencies.jar dk.designware.io_test.ZKIOTest ./io-test-files 10 1024 5000000 IP-of-ZooKeeper-server:2181 > ./io-test-files/stdouterr.txt 2>&1 &
首先创build10个5GB的文件(50GB比机器内存更多,所以OS文件caching帮助不大),然后启动一个ZooKeeper客户端(通过定期发送ping / heartbeats来保持与ZooKeeper服务器的连接) ,然后让10个线程随机访问到10个文件中,创build了大量的磁盘IO,但实际上并没有真正使用CPU。 我看到ZooKeeper客户端最终失去了连接(“Zk状态” – 打印停止说“连接” – 在stdouterr.txt中),这基本上是我不明白的。 ZooKeeper客户端线程只想发送几秒钟的小心跳,只有在20秒内无法做到这一点,才会失去连接。 我期望它可以轻松访问CPU,因为所有其他线程基本上只是在等待磁盘IO。
在testing期间,我看到以下使用“顶”
这里是我的一个运行的输出: https : //dl.dropboxusercontent.com/u/25718039/io-test-output.txt