2010-02-28 3 views
3

SalutationsTomcat6 sur Linux utilise 100% CPU chaque fois ServerSocket est inactif

Je courais mon webapp sur le Tomcat6 java6 sur Ubuntu8.04. La servlet principale de cette application ouvre un ServerSocket, avec le simple code suivant:

ServerSocket serverSocket = new ServerSocket(6767); 

Socket xmlSocket = serverSocket.accept();   

Bien sûr, cela fonctionne dans un thread séparé et avec les blocs try-catch nécessaires. Quand je lance Tomcat, il charge immédiatement 100% du CPU et reste là jusqu'à ce qu'un client se connecte sur le port 6767. Tant que le client est connecté, la charge descend à 0%. Dès que le client se déconnecte, la charge remonte à 100%.

Quelqu'un peut-il me dire de quoi il s'agit?

Merci!

SOLUTION:

Les deux réponses ci-dessous ont été très utiles. Le problème n'a pas réellement à faire avec le ServerSocket, mais avec une boucle sans sommeil tout en un fil complètement différent de l'application, mais aussi dépendant si un client a été connecté ou non.

J'ai été capable d'identifier les threads actifs avec la commande JDK "jstack", puis c'était facile de trouver celui avec la boucle d'emballement.

Merci pour l'aide! :)

Répondre

1

Dès que le client se déconnecte, la charge remonte à 100%.

Ceci est généralement le cas dans un "while loop" sans sleep(). Voir this thread pour l'illustration.

Exemple:

try 
{ 
    while (m_flagRunUserThreadManager) 
    { 
    try 
    { 
     m_listenSocket.setSoTimeout(10000); 
     Socket clientSocket = m_listenSocket.accept(); 
     //create a thread for client 
     MyClientHandler clientHandler = new ClientHandler(clientSocket); 
     clientHandler.setPriority(Thread.MIN_PRIORITY); 
     clientHandler.start(); 

    } 
    catch(SocketTimeoutException excp) 
    { 
     String strError = "No requests for 10 Sec."; 
     //display this message  
    } 
    } 
} 
catch(IOException excp) 
{ 
    // display the exception 
} 

Ceci est parce que votre while loop a un chemin à travers elle sans sommeil, en particulier lorsque votre essai échoue.
Vous avez besoin de dormir quelque part, donc d'autres threads/processus ont une chance. Soit cela ou ne continuez pas à essayer sur un client qui a déjà échoué.

+1

N'est-ce pas ServerSocket.accetp(); censé bloquer, et donne donc à tous les autres threads la chance de courir, jusqu'à ce qu'il obtient réellement une tentative de connexion d'un client? Ou est-ce que je comprends mal? – Lou

+0

@Lou: vrai; mais en fonction * où * vous appelez la méthode 'accept()', qui peut tout geler: voir http://stackoverflow.com/questions/2170551/programme-goes-unresponsive-at-serversocket-accept-java – VonC

+0

I J'ai ajouté sleep() et setSoTimeout (10000), ce qui est sûrement à la fois une bonne chose à faire et à rendre mon application plus robuste. Mais mon problème n'est pas que l'application ne répond pas, mais que la charge du processeur passe à 100% alors que accept() bloque (ou au moins cela semble). – Lou

2

Peut-être la meilleure façon de comprendre ce qui se passe est d'attendre à courir à 100%, et générer un fil par décharge Ctrl-Break (ou utilisez SendSignal ou similaire). Vous obtiendrez l'ensemble des threads avec leur état, et il devrait être évident de savoir lequel est en cours d'exécution et où il se trouve dans le code.

+0

Merci! Je viens de le faire, en utilisant la commande "jstack" qui est incluse avec le JDK et que vous pouvez ajouter à un PID. Semble être le moyen le plus simple :) Maintenant, je dois juste donner un sens à ce vidage de fil ... – Lou

Questions connexes