Domanda

Riscontro un problema su una macchina di prova che esegue Red Hat Linux (la versione del kernel è 2.4.21-37.ELsmp) utilizzando Java 1.6 (1.6.0_02 o 1.6.0_04). Il problema è che, una volta creato un certo numero di thread in un singolo gruppo di thread, il sistema operativo non è disposto o non è più in grado di crearlo.

Questo sembra essere specifico per la creazione di thread Java, in quanto il programma C thread-limit è stato in grado di creare circa 1,5k thread. Inoltre, ciò non accade con una JVM Java 1.4 ... può creare oltre 1.4k thread, sebbene siano ovviamente gestiti in modo diverso rispetto al sistema operativo.

In questo caso, il numero di thread che sta tagliando è di soli 29 thread. Questo è testabile con un semplice programma Java che crea solo thread fino a quando non viene visualizzato un errore e quindi stampa il numero di thread creati. L'errore è un

java.lang.OutOfMemoryError: unable to create new native thread

Questo sembra non essere influenzato da cose come il numero di thread in uso da altri processi o utenti o la quantità totale di memoria che il sistema sta usando in quel momento. Le impostazioni JVM come Xms, Xmx e Xss non sembrano cambiare nulla (il che è previsto, considerando che il problema sembra riguardare la creazione di thread del sistema operativo nativo).

L'output di " ulimit -a " è il seguente:

core file size        (blocks, -c) 0
data seg size         (kbytes, -d) unlimited
file size             (blocks, -f) unlimited
max locked memory     (kbytes, -l) 4
max memory size       (kbytes, -m) unlimited
open files                    (-n) 1024
pipe size          (512 bytes, -p) 8
stack size            (kbytes, -s) 10240
cpu time             (seconds, -t) unlimited
max user processes            (-u) 7168
virtual memory        (kbytes, -v) unlimited

Il limite del processo dell'utente non sembra essere il problema. La ricerca di informazioni su ciò che potrebbe essere sbagliato non è risultata molto, ma questo post sembra indicare che almeno alcuni kernel Red Hat limitano un processo a 300 MB di memoria allocata per lo stack e a 10 MB per thread per lo stack, sembra che il problema potrebbe essere lì (anche se sembra strano e improbabile come bene).

Ho provato a cambiare la dimensione dello stack con " ulimit -s " per testarlo, ma qualsiasi valore diverso da 10240 e JVM non inizia con un errore di:

Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.

In genere posso aggirare Linux, ma in realtà non so molto sulla configurazione del sistema e non sono stato in grado di trovare nulla che affronti specificamente questo tipo di situazione. Qualsiasi idea su quale sistema o impostazione JVM potrebbe causare questo sarebbe apprezzata.

Modifiche : esecuzione del programma thread-limit menzionato da plinth , non si sono verificati errori fino a quando non ha provato a creare il 1529 ° thread.

Inoltre, il problema non si è verificato utilizzando una JVM 1.4 (si verifica con JVM 1.6.0_02 e 1.6.0_04, al momento non è possibile eseguire il test con una JVM 1.5).

Il codice per il thread test che sto usando è il seguente:

public class ThreadTest {

   public static void main(String[] pArgs) throws Exception {

      try {
         // keep spawning new threads forever
         while (true) {
            new TestThread().start();
         }
      }
      // when out of memory error is reached, print out the number of
      // successful threads spawned and exit
      catch ( OutOfMemoryError e ) {
         System.out.println(TestThread.CREATE_COUNT);
         System.exit(-1);
      }
   }

   static class TestThread extends Thread {
      private static int CREATE_COUNT = 0;
      public TestThread() {
         CREATE_COUNT++;
      }
      // make the thread wait for eternity after being spawned
      public void run() {
         try {
            sleep(Integer.MAX_VALUE);
         }
         // even if there is an interruption, dont do anything
         catch (InterruptedException e) {
         }
      }
   }
}

Se lo esegui con una JVM 1.4, si bloccherà quando non può creare altri thread e richiede un kill -9 (almeno lo ha fatto per me).

Altre modifiche:

Si scopre che il sistema che sta riscontrando il problema utilizza il modello di threading LinuxThreads mentre un altro sistema che funziona correttamente utilizza il modello NPTL.

È stato utile?

Soluzione 2

L'aggiornamento del kernel a una versione più recente (2.6.something) con thread NPTL ha risolto questo problema.

Altri suggerimenti

Hai esaminato questa risorsa ? Indica che dovresti essere in grado di eseguire thread-limit per trovare il numero massimo di thread e puoi modificarlo compilando glibc.

Questo è con Ubuntu Linux (1GB RAM)

dsm@localhost:~$ javac ThreadTest.java 
dsm@localhost:~$ java ThreadTest 
8113
dsm@localhost:~$ java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
dsm@localhost:~$ 

Puoi provarlo con JRockit JVM? IIRC, aveva un modello di threading diverso rispetto allo stock Sun JVM.

Le impostazioni in /etc/security/limits.d/90-nproc.conf potrebbero sovrascrivere le impostazioni /etc/security/limits.conf . Ciò può comportare che il sistema agisca in un modo diverso mostrato in ulimit -u .

https://bugzilla.redhat.com/show_bug.cgi?id=823030

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top