web-dev-qa-db-fra.com

java.net.SocketException: trop de fichiers ouverts

J'ai une application Java qui fonctionne très bien (sous Ubuntu 10.04) pendant quelques heures jusqu'à l'apparition de "Java.net.SocketException: trop de fichiers ouverts". Le code pour Sender.Java peut être trouvé ici

Est-ce parce que je crée une nouvelle instance de HttpPut et HttpPost pour chaque thread? J'utilise HTTPClient 4 Apache-commons. 

Voici le journal des exceptions:

Java.net.SocketException: Too many open files
    at Java.net.Socket.createImpl(Socket.Java:414)
    at Java.net.Socket.connect(Socket.Java:544)
    at org.Apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.Java:123)
    at org.Apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.Java:133)
    at org.Apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.Java:149)
    at org.Apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.Java:108)
    at org.Apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.Java:415)
    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:641)
    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:576)
    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:554)
    at com.marketplace.io.Sender.doBasicHttpPost(Sender.Java:434)
    at com.marketplace.io.Sender.appVisualExists(Sender.Java:223)
    at com.marketplace.io.Sender.addVisualToCollection(Sender.Java:350)
    at com.marketplace.service.ImageThread.run(ImageThread.Java:136)
    at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:471)
    at Java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.Java:334)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:166)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1110)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:603)
    at Java.lang.Thread.run(Thread.Java:636)
14
Raunak

Sur la ligne 438, vous obtenez la réponse sous forme de flux et vous la convertissez en tableau d'octets. InputStream renvoyé par entity.getContent () n'est pas fermé. Cela pourrait contribuer au problème. En outre, HttpEntity.consumeContent () est obsolète pour des raisons connexes.

11
Wesley Hartford

"Java.net.SocketException: trop de fichiers ouverts" est visible dans n'importe quelle application Java Server, par exemple. Tomcat, Weblogic, WebSphere, etc., avec client se connectant et se déconnectant fréquemment. 

Veuillez noter que les connexions socket sont traitées comme des fichiers et utilisent un descripteur de fichier, qui est une ressource limitée. 

Les systèmes d'exploitation différents ont des limites différentes quant au nombre de descripteurs de fichiers qu'ils peuvent gérer. 

En bref, cette erreur survient car les clients se connectent et se déconnectent fréquemment. Si vous souhaitez la gérer de votre côté, vous avez deux options:

1) Augmentez le nombre de descripteurs de fichier ou de descripteurs de fichier ouverts par processus.

Dans un système d'exploitation basé sur UNIX, par exemple Ubuntu ou Solaris, vous pouvez utiliser la commande ulimit -a pour savoir combien de descripteurs de fichiers ouverts sont autorisés par processus.

$ ulimit -a
core file size        (blocks, -c) unlimited
data seg size         (kbytes, -d) unlimited
file size             (blocks, -f) unlimited
open files                    (-n) 256
pipe size          (512 bytes, -p) 10
stack size            (kbytes, -s) 8192
cpu time             (seconds, -t) unlimited
max user processes            (-u) 2048
virtual memory        (kbytes, -v) unlimited

Vous pouvez voir que les fichiers ouverts (-n) 256, ce qui signifie que seuls 256 descripteurs de fichiers ouverts par processus sont autorisés. Si votre programme Java, rappelez-vous Tomcat, weblogic ou tout autre serveur d'applications sont des programmes Java et qu'ils s'exécutent sur la machine virtuelle Java, dépasse cette limite, Java.net.SocketException: erreur d'ouverture de trop de fichiers.

Vous pouvez modifier cette limite en utilisant ulimit -n pour un nombre plus élevé, par exemple. 4096, mais faites-le avec l'avis de l'administrateur système UNIX et, si vous avez une équipe de support UNIX distinct, mieux vaut leur transmettre l'information.

2) Réduisez le délai d'expiration de l'état TIME_WAIT dans votre système d'exploitation

Sur les systèmes UNIX, vous pouvez voir la configuration actuelle dans le fichier / proc/sys/net/ipv4/tcp_fin_timeout

Dans les systèmes Windows, vous pouvez voir ces informations dans le registre Windows. Vous pouvez modifier le délai d'expiration TCPTIME_WAIT dans Windows en procédant comme suit:

1) Open Windows Registry Editor, by typing regedit in run command window
2) Find the key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters
3) Add a new key value pair TcpTimedWaitDelay asa decimal and set the desired timeout in seconds (60-240)
4) Restart your windows machine.
15
Tung Nguyen

Vous pouvez également vouloir vérifier la limite maximale de fichiers ouverts sous Linux. Ce lien lié est destiné à un produit Java sur mesure, mais il explique bien les étapes nécessaires à la résolution du problème.

7
DrUseful

(RÉSOLU)

J'ai récemment eu la même erreur parce que le var/log sur DataBase Server est Full.

#df -h
S.ficheros            Size  Used Avail Use% Montado en

/dev/cciss/c0d0p3     126G  126G    0G 100% /var


#echo "">/var/log/postgresql/postgresql.log

Maintenant, l'erreur est partie !!!

important: voyez ce que vous devez vous connecter sur postgresql.log

au revoir
@ _ jpgo

2
Juan

Je résous le problème en fermant la connexion dans le bloc finally。

public  static String postMethod(String jsonStr,String sendUrl){
    String resultJson = "";
    HttpClient httpClient = new HttpClient();
    PostMethod post = new PostMethod(sendUrl);
    post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");  
    NameValuePair[] param = { new NameValuePair("message",jsonStr)} ;
    post.setRequestBody(param);
    try {
        httpClient.executeMethod(post);
        resultJson = post.getResponseBodyAsString();
    } catch (HttpException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
         post.releaseConnection();
         ((SimpleHttpConnectionManager)httpClient.getHttpConnectionManager()).shutdown();
    }
    return resultJson;
}
0
Roronoa Zoro