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