我创建了一个线程池,并为它提供了50个任务来连接到服务器。所以一旦完成连接,发送一些数据,然后断开连接。它也有一个读取超时设置为5秒(当然是5000长)。我甚至将线程池设置为最大大小1.然后,我在linux上启动它,并运行htop(top的更好的版本)来检查CPU使用情况。我始终在100%的时间内看到我的一个核心(2核心机器)。我使用hprof(-agentlib:hprof=cpu=samples,interval=20,depth=3
)对它进行了描述,并且使用99.%的socket.connect()。为什么Java的socket.connect()消耗100%cpu资源?
这里是我发现很奇怪,是不是阻止IO阻止点(因此等待)?我的JDK是(从java -version
):
OpenJDK Runtime Environment (IcedTea6 1.6.1) (6b16-1.6.1-3ubuntu3)
OpenJDK Server VM (build 14.0-b16, mixed mode)
UPDATE1:Sun的JVM会发生同样的问题太多:
java -version
Java version "1.6.0_20"
UPDATE2:这是由于本地的doConnect方法。任何人都知道我可以如何查看本机/ C代码的来源?
Update3:我登录到Windows编写代码并测试它。它运行良好,没有CPU资源被洗净。我重新登录到Linux和现在的问题是还在这里,但不作为服务器作为软管整个CPU核心在100%的仅有1连接....下面是代码:
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class SocketTest {
public static void main(String[] args) {
new SocketTest();
}
public SocketTest() {
ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(40);
Vector<Callable<Object>> tasks = new Vector<Callable<Object>>();
for (int i = 0; i < 1500; i++)
tpe.submit(new Thread() {
public void run() {
byte[] ip = { 74, 125, 19, (byte)((Math.random()*253)+1)};
Socket socket = new Socket();
try {
System.out.println("new thread: "+ip[3]);
socket.connect(new InetSocketAddress(InetAddress.getByAddress(ip), 80), 3000);
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
//no need to print
}
}
});
try {
tpe.invokeAll(tasks);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("test");
try {
//too lazy to write actual code to wait for task completness...
tpe.awaitTermination(9001, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test2");
}
}
有任何代码向我们展示? – 2010-06-05 01:08:23
代码中必须有东西,你可以发布相关的部分。您可能需要分解出导致问题的最低代码量。 – 2010-06-05 02:51:51
请参阅update2。它出现在PlainSocketImpl的doConnect方法中。这就是变得虚弱。没有任何方法可以让我吃掉CPU ...... – Zombies 2010-06-05 03:07:12