2010-08-17 21 views
6

ho visto commento come questojava.lang.OutOfMemoryError: impossibile creare un nuovo thread nativo

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

sul Sun Java Forums

Nella mia applicazione, initialy si prevede di utilizzare filo, ma più tardi, abbiamo deciso non serve più, quindi chiamiamo run() invece di start(). Abbiamo bisogno di fare il GC manuale per il nuovo threadClass (..)?

mia impostazione

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

Tuttavia, se si esegue excute run() anziché start(), la JVM non creerà un nuovo thread. Non è vero? – sourcerebels

+0

concordato. quindi, anche se uso la nuova threadClass (..) sul mio metodo di livello di servizio, non è necessario eseguire la pulizia manuale? – cometta

+0

Perché è necessario creare Thread all'interno di Tomcat (un server Web)? Non è raccomandato Prova a trovare una soluzione alternativa: 1) un processo autonomo separato con thread che comunicano tramite RMI, JMS o un database; 2) magari usando MessageDrivenBeans e un JMS all'interno della tua applicazione web, se sei d'accordo con il passaggio a un app server J2EE come JBoss, Glassfish o Geronimo; 3) altro ... :) – helios

risposta

11

Perché si crea un Thread in primo luogo?

Il codice deve invece implementare l'interfaccia Runnable.

Poi, quando si decide che si desidera eseguire in un thread, semplice creare un'istanza di un Thread con la Runnable come argomento e chiamare start() sull'oggetto Thread.

Se, invece, si desidera eseguirlo nel thread corrente, è sufficiente chiamare run() sull'oggetto Runnable.

Questo ha diversi vantaggi:

  • non comporta alcun Thread oggetti fintanto che non si cura di thread separati
  • il codice è avvolto in un Runnable che si adatta più vicini concettualmente: si Non stai scrivendo un particolare tipo di discussione, vero? Basta scrivere un codice che può essere eseguito/eseguito.
  • si può facilmente passare ad usare un Executor che ha ulteriormente astrarre la decisione

E, ultimo ma non meno importante evitare qualsiasi potenziale confusione su se o non si crea una risorsa thread nativo.

+0

vuoi dire che il mio threadClass estende Thread causa questo problema?anche se ho appena chiamato run(), invece di iniziare? – cometta

+2

@cornetta - non sta dicendo che causa problemi. Sta dicendo che è * scarsa pratica * estendere 'Thread'. –

+0

Inoltre, nello stesso senso, perché non usare un Executor? –

4

quando si chiama metodo run() nessun nuovo thread deve essere creato di avvio di Tomcat. E i tuoi oggetti saranno raccolti da Garbage Collector quando non sono referenziati.

L'altra parte di codice potrebbe creare molti thread.

Provare a utilizzare ThreadPoolExecutor (thread pooling) nel codice per limitare i thread nell'applicazione e ottimizzare le dimensioni del threadpool di conseguenza per prestazioni migliori.

è anche possibile controllare in seguito per eseguire il debug il problema: (riferimento da link) Ci sono un paio di cose da fare se si verifica questa eccezione.

  • utilizzare il comando PID lsof -p (Unix piattaforme) per visualizzare il numero di fili sono attivi per questo processo.
  • Determinare se esiste un numero massimo di thread per processo definito dal sistema operativo. Se il limite è troppo basso per l'applicazione, prova a aumentando il limite del thread per processo.
  • esaminare il codice di applicazione per determinare se v'è codice creando fili o connessioni (ad come connessioni LDAP) e non distruggerli. È possibile scaricare i thread Java per verificare se è stato creato un numero eccessivo .
  • Se si rileva che troppe connessioni vengono aperte dall'applicazione, rendere sicuro che qualsiasi thread creato dall'applicazione venga distrutto. Un'applicazione aziendale enterprise (.ear) o Web (.war) viene eseguita con una JVM di lunga durata . Solo perché l'applicazione è terminata non significa che termina il processo JVM. È imperativo che un'applicazione gratuita eventuali risorse che alloca. Un'altra soluzione potrebbe essere che l'applicazione utilizzi un pool di thread su per gestire i thread necessari.
1

Questo link descrive abbastanza bene come questo errore viene generato dalla JVM: http://javaeesupportpatterns.blogspot.ro/2012/09/outofmemoryerror-unable-to-create-new.html

In sostanza è molto dipendente dal sistema operativo. Su RedHat Linux 6.5 (molto probabilmente altre distro/versione e versioni del kernel) max_threads = max_process x 2.

Il numero massimo di thread dipende molto dal numero di processi consentiti. Quale il numero massimo di processi dipende dalla memoria fisica massima installata.

Se si ha un aspetto nel file limits.conf (sulla mia RHL 6.5 è in /etc/security/limits.d/90-nproc.conf). Esercitano formare il file:

# 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 

Vedrai che per gli utenti non di root si tratta di 1024 (il che significa che le discussioni 2048 max).

Per vedere il numero massimo di thread che l'utente è autorizzato a creare eseguire questo comando "cat/proc/sys/kernel/threads-max" o "sysctl kernel.threads-max".

Per risolvere un problema come questo (almeno ha funzionato per me) come root è necessario aumentare l massimo consentito discussioni:

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

Questo riguarda tutti gli utenti e il root. L'utente deve disconnettersi e quindi accedere nuovamente per rendere effettive le impostazioni.

Problemi correlati