2012-01-25 13 views
16
Program

My Java jest zepsuty zZbyt wiele otwartych plików, ale błąd lsof pokazuje liczbę prawnej otwartych plików

Caused by: java.io.IOException: Too many open files 
     at java.io.UnixFileSystem.createFileExclusively(Native Method) 
     at java.io.File.createNewFile(File.java:883)... 

Tutaj są kluczowymi linie z /etc/security/limits.conf. Określają one maksymalnie pliki dla użytkownika przy 500K:

root      soft nofile   500000 
root      hard nofile   500000 
*      soft nofile   500000 
*      hard nofile   500000 

Pobiegłem lsof aby policzyć liczbę plików otworzyć - zarówno w skali globalnej, a przez proces JVM. Zbadałem liczniki w /proc/sys/fs. Wszystko wydaje się w porządku. Mój proces ma tylko 4301 plików otwartych, a limit wynosi 500k:

:~# lsof | wc -l 
5526 
:~# lsof -uusername | wc -l 
4301 
:~# cat /proc/sys/fs/file-max 
744363 
:~# cat /proc/sys/fs/file-max 
744363 
:~# cat /proc/sys/fs/file-nr 
4736 0  744363 

To jest serwer Ubuntu 11.04. Nawet się zrestartowałem, więc jestem pewien, że te parametry są używane.

Nie wiem, czy to istotne, ale proces jest uruchamiany przez upstart skryptu, który rozpoczyna proces używając setuidgid, tak:

exec setuidgid username java $JAVA_OPTS -jar myprogram.jar 

Czego mi brakuje?

+0

Spróbuj zaktualizować przestrzeń sterty i zwiększyć ją. Nie wiem, dlaczego te dwie rzeczy byłyby powiązane, ale trafiłem na ten błąd z powodu wielu różnych problemów. – Relic

+0

Interesujące, dzięki. Ale już jest - Xmx5800m :) – hughw

+0

gdzieś w drzewie procesu ustawiasz nowe limity używając ulimit? – Jayan

Odpowiedz

16

Okazuje się, że problemem było to, że mój program został uruchomiony jako skrypcie upstart i że exec strofa nie wywołaj powłokę. ulimit, a ustawienia w pliku limits.conf mają zastosowanie tylko do procesów użytkownika w powłoce.

I to zweryfikowane przez zmianę exec pokoju do

exec sudo -u username java $JAVA_OPTS -jar program.jar 

czyli Java w domyślnej powłoki Nazwa użytkownika za. To pozwoliło programowi na korzystanie z tak wielu otwartych plików, ile potrzebuje.

I have seen it mentioned, przed wywołaniem polecenia można również zadzwonić pod numer ulimit -n; dla skryptu upstart myślę, że zamiast tego używałbyś zwrotki script.

Znalazłem lepszą diagnostykę niż lsof na ls /proc/{pid}/fd | wc -l, aby uzyskać dokładną liczbę otwartego deskryptora pliku. Dzięki monitorowaniu mogłem zauważyć, że awarie wystąpiły dokładnie na 4096 otwartych dyskach. Nie wiem skąd pochodzi 4096; nie jest nigdzie w/etc; Domyślam się, że jest wkompilowany w jądro.

4

Mam ten fragment bash na górze skryptu tworzenia serwera:

# Jack up the max number of open file descriptors at the kernel 
echo "fs.file-max = 1000000" >> /etc/sysctl.conf 
invoke-rc.d procps start 

# Increase max open file descriptors for this process 
ulimit -n 1000000 

# And for future ones as well 
cat >> /etc/profile <<LIMITS 
ulimit -n 1000000 
LIMITS 
cat >> /etc/security/limits.conf <<LIMITS 
root - nofile 1000000 
LIMITS 
Powiązane problemy