2010-06-05 4 views
4

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"); 
    } 

} 
+1

Avoir un code pour nous montrer? –

+0

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. –

+0

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

Répondre

0

Je viens Je voulais commenter qu'il semble que vous abusiez du pool de threads, puisque vous instanciez réellement de nouveaux objets de type Thread 1500 fois, seulement pour les passer à un pool de threads qui instancie plus de threads afin d'exécuter vos tâches. Ce que vous devriez normalement faire est instancier un Runnable et laisser le thread-pool faire son travail. Je ne dis pas que c'est ce qui provoque l'étouffement du processeur, mais c'est un problème.

+0

Je pense que le Threadpooling peut être ignoré ici. Je n'aurais pas dû donner un exemple avec ça dans le code car ce n'est pas pertinent et je suis juste paresseux à ce sujet. – Zombies

0

En mettant de côté les problèmes de conception avec le code (par exemple, tasks n'est jamais vraiment utilisé), je ne pouvais pas reproduire l'utilisation élevée du processeur sur Windows ou Ubuntu (12.04.2 LTS).

Pouvez-vous s'il vous plaît mettre à jour votre JDK à 1,7 (sudo apt-get install openjdk-7-jdk) et laissez-moi savoir quelle version du JDK vous utilisez? Le mien est javac 1.7.0_25, par exemple (je me suis à l'aide javac -version)

Je vais essayer de creuser plus loin après ...

Questions connexes