2010-08-17 16 views
6

vi comentario como estejava.lang.OutOfMemoryError: no puede crear nuevo hilo nativa

one place i have seen this problem is if you keep creating threads, and instead of calling start(), call run() directly on the thread object. This will result in the thread object not getting dereferenced... So after sometime the message unable to create new native thread comes up

en el Sun Java Forums

En mi solicitud, initialy tenemos la intención de utilizar el hilo, pero más tarde, decidimos ya no es necesario, así que simplemente llamamos run() en lugar de start(). ¿Necesitamos hacer una GC manual para la nueva threadClass (..)?

mi Tomcat establecer

-Xms1024m -Xmx1024m -XX:MaxPermSize=450m 
+3

Pero, si ejecutas run() en lugar de start(), la JVM no creará un nuevo hilo. ¿No es así? – sourcerebels

+0

de acuerdo. así que, aunque uso un nuevo threadClass (..) en mi método de capa de servicio, ¿no es necesario realizar una limpieza manual? – cometta

+0

¿Por qué necesita crear subprocesos dentro de Tomcat (un servidor web)? No es recomendado Intente encontrar una solución alternativa: 1) un proceso independiente separado con hilos que se comunican a través de RMI, JMS o una base de datos; 2) tal vez usando MessageDrivenBeans y un JMS dentro de su aplicación web, si está bien con el cambio a un servidor de aplicaciones J2EE como JBoss, Glassfish o Geronimo; 3) otro ... :) – helios

Respuesta

11

¿Por qué creas un Thread en primer lugar?

En su lugar, el código debe implementar la interfaz Runnable.

Entonces, cuando usted decide que desea que se ejecute en un hilo, instantiate sencilla un Thread con el Runnable como el argumento y llamar start() en el objeto Thread.

Si, en cambio, solo desea ejecutarlo en su hilo actual, simplemente llame al run() en su objeto Runnable.

Esto tiene varias ventajas:

  • no implica ningún Thread objetos, siempre y cuando no se preocupan por hilos separados
  • su código está envuelto en una Runnable que se ajusta más cerca conceptualmente: se No estoy escribiendo algún tipo especial de hilo, ¿verdad? Simplemente escribe un código que se puede ejecutar/ejecutar.
  • se puede cambiar fácilmente a las cuales un Executor pero abstraer la decisión

Y por último, más no menos importante evitar cualquier posible confusión sobre si o no se crea un recurso nativo para subprocesos.

+0

quieres decir que mi threadClass extends Thread causa este problema?a pesar de que acabo de llamar a run(), en lugar de comenzar? – cometta

+2

@cornetta - él no dice que causa problemas. Él dice que es * una práctica deficiente * extender 'Thread'. –

+0

Además, en la misma línea, ¿por qué no utilizar un ejecutor? –

4

Cuando() método que no sea nuevo hilo debe ser creado que llamamos ejecutar el arranque. Y sus objetos serán recolectados por Garbage collector cuando no estén referenciados.

Su otra parte del código puede estar creando muchos subprocesos.

Pruebe usar ThreadPoolExecutor (agrupamiento de subprocesos) en su código para limitar los subprocesos en su aplicación, y ajuste el tamaño de su subproceso en consecuencia para un mejor rendimiento.

También puede comprobar siguiente para depurar el problema: (referenciado de enlace) Hay algunas cosas que hacer si se encuentra con esta excepción.

  • utilizar el comando lsof -p PID (Unix plataformas) para ver cuántos hilos son activos para este proceso.
  • Determine si hay un número máximo de cantidad de subprocesos por proceso definido por el sistema operativo. Si el límite es demasiado bajo para la aplicación, intente con elevando el límite del hilo por proceso.
  • Examine el código de aplicación para determinar si hay código que es creación de hilos o conexiones (tales como conexiones LDAP) y no destruyéndolos. Puede volcar los hilos de Java para ver si se ha creado un número excesivo .
  • Si la aplicación abre demasiadas conexiones , asegúrese de que se destruye cualquier subproceso creado por la aplicación . Una aplicación empresarial (.ear) o la aplicación Web (.war) se ejecuta bajo una JVM de larga ejecución . El hecho de que la aplicación finalice no significa que finaliza el proceso de JVM. Es imprescindible que una aplicación libere los recursos que asigna. Otra solución sería que la aplicación utilizara un grupo de subprocesos para administrar los subprocesos necesarios.
1

Este enlace describe muy bien cómo este error se produce por la JVM: http://javaeesupportpatterns.blogspot.ro/2012/09/outofmemoryerror-unable-to-create-new.html

Básicamente es muy dependiente del sistema operativo. En RedHat Linux 6.5 (lo más probable es que otras distros/versiones y versiones de kernel) max_threads = max_process x 2.

El número máximo de subprocesos depende en gran medida de la cantidad de procesos permitidos. La cantidad máxima de procesos depende de la memoria física máxima que ha instalado.

Si echas un vistazo al archivo limits.conf (en mi RHL 6.5 está en /etc/security/limits.d/90-nproc.conf). Ejercen formar el archivo:

# Default limit for number of user's processes to prevent 
# accidental fork bombs. 
# See rhbz #432903 for reasoning. 

*   soft nproc  **1024** 
root  soft nproc  unlimited 

Vas a ver que para usuarios no root Es 1024 (lo que significa 2.048 hilos max).

Para ver el número máximo de subprocesos que su usuario puede crear, ejecute este comando "cat/proc/sys/kernel/threads-max" o "sysctl kernel.threads-max".

Para resolver un problema como este (al menos funcionó para mí) como root tendrá que aumentar la cant máximo permitido hilos:

eco 10000>/proc/sys/kernel/threads-max

Esto afecta a todos los usuarios y la raíz. El usuario debe cerrar sesión y luego iniciar sesión de nuevo para que la configuración surta efecto.

Cuestiones relacionadas