IOException: Trop de fichiers ouverts
Je suis en train de déboguer un descripteur de fichier de fuite dans une Java webapp cours d'exécution dans la Jetée 7.0.1 sur Linux.
L'application avait été heureux en cours d'exécution pour un mois ou lorsque la demande a commencé à échouer en raison de trop de fichiers ouverts, et de la Jetée a dû être redémarré.
java.io.IOException: Cannot run program [external program]: java.io.IOException: error=24, Too many open files
at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
at java.lang.Runtime.exec(Runtime.java:593)
at org.apache.commons.exec.launcher.Java13CommandLauncher.exec(Java13CommandLauncher.java:58)
at org.apache.commons.exec.DefaultExecutor.launch(DefaultExecutor.java:246)
Au début, je pensais que le problème était avec le code qui lance le programme externe, mais c'est à l'aide de communes-exec et je ne vois rien de mal à cela:
CommandLine command = new CommandLine("/path/to/command")
.addArgument("...");
ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream();
Executor executor = new DefaultExecutor();
executor.setWatchdog(new ExecuteWatchdog(PROCESS_TIMEOUT));
executor.setStreamHandler(new PumpStreamHandler(null, errorBuffer));
try {
executor.execute(command);
} catch (ExecuteException executeException) {
if (executeException.getExitValue() == EXIT_CODE_TIMEOUT) {
throw new MyCommandException("timeout");
} else {
throw new MyCommandException(errorBuffer.toString("UTF-8"));
}
}
Liste des fichiers ouverts sur le serveur, je peut voir un grand nombre de mémoires Fifo:
# lsof -u jetty
...
java 524 jetty 218w FIFO 0,6 0t0 19404236 pipe
java 524 jetty 219r FIFO 0,6 0t0 19404008 pipe
java 524 jetty 220r FIFO 0,6 0t0 19404237 pipe
java 524 jetty 222r FIFO 0,6 0t0 19404238 pipe
lors de la Jetée commence il y a juste 10 Fifo, après quelques jours, il ya des centaines d'entre eux.
Je sais que c'est un peu vague, à ce stade, mais avez-vous des suggestions sur où chercher la prochaine, ou comment obtenir des informations plus détaillées à propos de ces descripteurs de fichiers?
- Voyons voir un peu de code
- Ajouté le code de lancement le programme externe.
- En tant que source supplémentaire de informaiton netstat-anp --tcp|grep <PID> --la couleur peut être
- ajouter enfin le bloc après le try-catch et de fermer tous les volets. Il pourrait être possible que les flux ne sont pas fermer correctement et à cet effet, vous avez eu cette erreur. Notez également que linux traite les connexions ouvertes en compte dans les fichiers ouverts, afin de vérifier ur le code pour ouvrir la connexion.
- Voir aussi stackoverflow.com/questions/4289447/java-too-many-open-files
Vous devez vous connecter pour publier un commentaire.
Votre programme externe ne se comporte pas correctement. Jetez un oeil à pourquoi il ne le fait pas.
Le problème vient de votre application Java (ou une bibliothèque que vous utilisez).
Première, vous devriez lire l'ensemble des sorties (Google pour StreamGobbler), et pronto!
Javadoc dit:
Deuxièmement,
waitFor()
votre processus à arrêter.Ensuite, vous devez fermer l'entrée, de la sortie d'erreur et de flux.
Enfin
destroy()
votre Processus.Mes sources:
waitFor()
a réussi. Le processus a déjà quitté.Que vous êtes en cours d'exécution sur Linux je soupçonne que vous êtes à court de descripteurs de fichiers. Découvrez ulimit. Voici un article qui décrit le problème: http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/
/etc/security/limits.conf
déjà pour d'autres raisons.Ne sais pas la nature de votre application, mais j'ai vu cette erreur se manifeste à plusieurs reprises en raison d'un pool de connexions de fuite, alors que ce serait la peine de vérifier. Sur Linux, les connexions socket consommer des descripteurs de fichiers ainsi que les fichiers du système de fichiers. Juste une pensée.
Côté de la recherche en cause des questions telles que le fichier de fuites, etc. dans le but de faire un légitime d'augmenter le "ouvrir des fichiers" limite et avoir qui persistent malgré les redémarrages, envisager la modification de
en ajoutant quelque chose comme cela
où "la jetée" est le nom d'utilisateur dans ce cas. Pour plus de détails sur les limites.conf, voir http://linux.die.net/man/5/limits.conf
déconnectez puis reconnectez-vous et exécuter
pour vérifier que la modification a eu lieu. De nouveaux processus par cet utilisateur doit maintenant se conformer à ce changement. Ce lien semble décrire la façon d'appliquer la limite sur les processus déjà en cours, mais je ne l'ai pas essayé.
La limite par défaut de 1024 peut être trop faible pour les grandes applications Java.
Vous pouvez gérer les fds vous-même. L'exec en java retourne un objet de Processus. Par intermittence vérifier si le processus est toujours en cours d'exécution. Une fois qu'il a terminé près le processus STDERR, STDIN et STDOUT flux (par exemple, proc.getErrorStream.close()). Qui permettront d'atténuer les fuites.
Ce problème vient lors de l'écriture de données dans plusieurs fichiers en même temps et de votre Système d'Exploitation a une limite fixe de fichiers Ouverts. Sous Linux, vous pouvez augmenter la limite d'ouvrir des fichiers.
https://www.tecmint.com/increase-set-open-file-limits-in-linux/
Comment puis-je modifier le nombre de fichiers ouverts limite dans Linux?