我創建了一個線程池,併爲它提供了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