Eine Java Applikation hat immer java.IO.Exception: Too many open files geworfen. Nun, normalerweise ist das ein eindeutiges Zeichen für einen Programmierfehler, es sei denn man braucht wirklich weit mehr als 50.000 Filehandles. Anstelle das Problem an der Wurzel zu fassen, kann man natürlich Linux dazu bringen, mit mehr File Handles zu arbeiten. cat /proc/sys/fs/file-max zeigt das momentane Maximum. Mit lsof -X|wc -l erfährt man wieviel Files derzeit geöffnet sind. Wobei man natürlich berücksichtigen muß, das unter *nix alles als Datei zählt, also auch Pipes, Sockets usw. Deshalb das -X, das lässt TCP/UPD weg. Mit sysctl -A|grep fs.file-max sieht man, was der Max Wert ist. In /etc/sysctl.conf ist wahrscheinlich noch keine Zeile für fs.file-max vorhanden. Wenn nicht, oder ein kleiner Wert drinnen steht, kann man z.B. fs.file-max=200000 setzen. Die Änderung kann man dem Kernel mit mitteilen, indem man sysctl -p aufruft.
Noch ein Wort zur Anzahl der geöffneten Files. Die Anzahl der geöffneten Files ist immer sehr hoch, fast möchte man der Angabe mißstrauen, aber nur, um mal ein Beispiel zu geben. Wenn man sich mit nano readme eine Datei ansieht, wieviel Dateien sind dann dafür geöffnet wurden? (Dateien im Sinne von *nix)
lsof -p 14009 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME nano 14009 bed cwd DIR 3,1 4096 114898 /home/bed nano 14009 bed rtd DIR 3,1 4096 2 / nano 14009 bed txt REG 3,1 149600 147216 /bin/nano nano 14009 bed mem REG 3,1 1282912 139241 /usr/lib/locale/locale-archive nano 14009 bed mem REG 3,1 9680 229783 /lib/i686/cmov/libdl-2.7.so nano 14009 bed mem REG 3,1 1413540 229045 /lib/i686/cmov/libc-2.7.so nano 14009 bed mem REG 3,1 249836 204406 /lib/libncursesw.so.5.7 nano 14009 bed mem REG 3,1 37776 199842 /usr/share/locale/de/LC_MESSAGES/nano.mo nano 14009 bed mem REG 3,1 25700 197817 /usr/lib/gconv/gconv-modules.cache nano 14009 bed mem REG 3,1 113248 204464 /lib/ld-2.7.so nano 14009 bed 0u CHR 136,11 13 /dev/pts/11 nano 14009 bed 1u CHR 136,11 13 /dev/pts/11 nano 14009 bed 2u CHR 136,11 13 /dev/pts/11
Also 13, beeindruckend, oder? Und nano ist weiß Gott nicht die Krone der Editoren. gedit schafft es in diesem Beispiel auf sage und schreibe 137! Da kommt auf einem laufenden System also ganz schön was zusammen.
Aber es gibt auch noch einen weiteren Grund für die eingangs erwähnte Fehlermeldung Too many open files. Denn häufig ist es nicht das Systemlimit, sondern das userlimit, welches einem da einen Strich durch die Rechnung macht. Anders, als man es häufig liest, ist die Aussage von ulimit nicht aussagekräftig. Die Meldung unlimited jedenfalls darf man nicht falsch verstehen. Erst ein ulimit -n zeigt die wirklich mögliche maximale Zahl der offenen Files. Default ist hier bei Debian artigen Distributionen 1024.
Nun kan ein gewöhnlicher Sterblicher nicht einfach ulimit -n 8192 eingeben, das geht nur als root und gilt dann auch nur für ihn.
Man muß in /etc/security/limits.conf für den betreffenden User einen Eintrag anlegen. Z.B. Für den User horst:
horst - nofile 8192
Danach kann der user horst sich einloggen und mit ulimit -n überprüfen, ob nun das Limit auf 8192 gestellt ist. Verkleinern kann horst es übrigens jederzeit, aber nicht wieder erhöhen. So, nun kann er den java Client wieder starten und hat keine Probleme mehr
Sehr praktisch, nicht nur für Java. Der Fehler kam soeben bei Transmission - aber jetzt dank diesem Blogpost nicht mehr.
Vielen Dank für den Super TIP!!!!!
Java Tomcat kann ein zickiges Bist sein aber wenn er mal läuft ist alles gut
Prima! Ich freue mich immer, wenn ich helfen kann Vor allem freut mich, das ich es nun auch selber verstanden habe
Hi,
tolle Anleitung, habe sie nun schon diverse male gebrauchen können
Was man noch erwähnen könnte, wenn man den User-Account für den der nofile Wert in der limits.conf nur über "su username" einloggt und nie über eine direkte SSH Verbindung, dann muss man, zumindest in meinem Debian Lenny, in der /etc/pam.d/su die Auskommentierung bei der unten genannten Zeile rückgängig machen. Weil sonst beim Login über "su username" die limits.conf nicht überprüft wird.
session required pam_limits.so
Gruß, Daniel
Gut zu wissen, wußte ich nicht