J'ai créé un pool de threads et lui ai donné 50 tâches pour me connecter à un serveur. Donc, une fois la connexion terminée, l'envoi de certaines données, puis la déconnexion. Il a également un timeout de lecture fixé à 5 secondes (5000 longtemps bien sûr). J'ai même mis le pool de threads à une taille maximale de 1. Je lance ensuite cela, sur Linux, et a couru htop (une meilleure version de top) pour vérifier l'utilisation du processeur. J'ai toujours vu un de mes noyaux (machine à 2 noyaux) à 100% tout le temps. J'ai profilé cela avec hprof (-agentlib:hprof=cpu=samples,interval=20,depth=3
) et avait socket.connect() à 99%.Pourquoi le fichier socket.connect() Java utilise-t-il 100% de ressources cpu?
Voici ce que je trouve bizarre, n'est pas le point de bloquer IO à bloquer (donc attendre)? Mon JDK est (de java -version
):
OpenJDK Runtime Environment (IcedTea6 1.6.1) (6b16-1.6.1-3ubuntu3)
OpenJDK Server VM (build 14.0-b16, mixed mode)
Update1: ce même problème se produit sur la machine virtuelle Java trop de Sun:
java -version
Java version "1.6.0_20"
Update2: Cela est dû à la méthode doConnect qui est native. Quelqu'un sait comment je peux voir la source de ce code natif/C?
Mise à jour3: Je me suis connecté à Windows pour écrire le code et le tester. Cela a fonctionné très bien, aucune ressource de CPU étant arrosée. retour je me connecte à Linux, et maintenant le problème est toujours là, mais pas aussi sever pour hose l'ensemble noyau du processeur à 100% pour seulement 1 se connecter .... Voici le code:
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");
}
}
Avoir un code pour nous montrer? –
Il doit y avoir quelque chose dans le code, pouvez-vous poster les parties pertinentes. Vous aurez probablement besoin de factoriser à la plus petite quantité de code qui vous donne le problème. –
voir update2. Il se produit dans la méthode doConnect à l'intérieur de PlainSocketImpl. C'est ce qui est arrosé. Il n'y a aucune méthode que j'ai qui est en train de manger le CPU ..... – Zombies