2012-01-25 14 views
16
programa

Mi Java está fallando conDemasiados errores archivos abiertos pero lsof muestra un número legal de archivos abiertos

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

Aquí están las líneas principales de /etc/security/limits.conf. Se pusieron los archivos máximo para un usuario en 500k:

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

me encontré lsof a contar el número de archivos abiertos - tanto a nivel mundial y por el proceso de JVM. Examiné los contadores en /proc/sys/fs. Todo parece estar bien. Mi proceso solo tiene 4301 archivos abiertos y el límite es 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 

Este es un servidor Ubuntu 11.04. Incluso he reiniciado, así que estoy seguro de que estos parámetros se están utilizando.

No sé si es relevante, pero el proceso se inicia mediante una secuencia de comandos advenedizo, que se inicia el proceso usando setuidgid, así:

exec setuidgid username java $JAVA_OPTS -jar myprogram.jar 

lo que me falta?

+0

Intente actualizar su espacio de montón y dándole un mayor tamaño máximo. No estoy seguro de por qué los dos estarían relacionados, pero acerté ese error por una miríada de problemas diferentes. – Relic

+0

Interesante, gracias. Pero ya es -Xmx5800m :) – hughw

+0

en algún lugar del árbol de procesos ¿estás estableciendo nuevos límites usando ulimit? – Jayan

Respuesta

16

Resulta que el problema era que mi programa se ejecuta como un guión de inicio recién llegado, y que el exec estrofa no lo hace invocar un caparazón. ulimit y las configuraciones en limits.conf se aplican solo a procesos de usuario en un shell.

I verificado esto cambiando la estrofa exec a

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

que corre java en el shell predeterminado del nombre de usuario. Eso permitió que el programa utilizara tantos archivos abiertos como fuera necesario.

I have seen it mentioned que también puede llamar al ulimit -n antes de invocar el comando; para un script advenedizo, creo que usaría una estrofa script en su lugar.

Encontré un mejor diagnóstico que lsof para ser ls /proc/{pid}/fd | wc -l, para obtener un recuento preciso del descriptor de archivo abierto. Al monitorear, pude ver que los fallos ocurrieron justo en 4096 fds abiertos. No sé de dónde viene ese 4096; no está en/etc en ningún lado; Supongo que está compilado en el kernel.

4

que tienen este fragmento de fiesta en la parte superior de un script de creación de servidor:

# 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 
Cuestiones relacionadas