Baixo limite de thread de processo único em Java no Red Hat Linux

Estou tendo um problema em uma máquina de teste que executa o Red Hat Linux (a versão do kernel é 2.4.21-37.ELsmp) usando o Java 1.6 (1.6.0_02 ou 1.6.0_04). O problema é que, quando um determinado número de threads é criado em um único grupo de threads, o sistema operacional não deseja ou não pode criar mais.

Isso parece ser específico para a criação de encadeamentos Java, já que o programa de limite de encadeamento C foi capaz de criar encadeamentos de 1.5k. Além disso, isso não acontece com uma JVM Java 1.4 ... ela pode criar encadeamentos acima de 1,4k, embora eles estejam obviamente sendo tratados de maneira diferente em relação ao sistema operacional.

Nesse caso, o número de encadeamentos em que está sendo cortada é de apenas 29 encadeamentos. Isso é testável com um programa Java simples que apenas cria encadeamentos até obter um erro e, em seguida, imprime o número de encadeamentos criados. O erro é um

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

Isso parece não ser afetado por coisas como o número de threads em uso por outros processos ou usuários ou a quantidade total de memória que o sistema está usando no momento. As configurações da JVM como Xms, Xmx e Xss também não parecem alterar nada (o que é esperado, considerando que o problema parece estar na criação de threads do SO nativa).

A saída de "ulimit -a" é a seguinte:

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

O limite do processo do usuário não parece ser o problema. Buscar informações sobre o que pode estar errado não apareceu muito, masesta postagem parece indicar que pelo menos alguns kernels da Red Hat limitam um processo a 300 MB de memória alocada para stack, e a 10 MB por thread para stack, parece que o problema pode estar lá (embora pareça estranho e improvável também).

Eu tentei alterar o tamanho da pilha com "ulimit -s" para testar isso, mas qualquer valor diferente de 10240 e a JVM não inicia com um erro de:

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

Eu geralmente posso contornar o Linux, mas eu realmente não sei muito sobre a configuração do sistema, e eu não consegui encontrar nada especificamente sobre esse tipo de situação. Quaisquer idéias sobre quais configurações do sistema ou da JVM poderiam estar causando isso seriam apreciadas.

Edições: Executando o programa de limite de encadeamento mencionado porplinto, não houve falha até que tentou criar o segmento 1529.

O problema também não ocorreu usando uma JVM 1.4 (ocorre com as JVMs 1.6.0_02 e 1.6.0_04, não é possível testar com uma JVM 1.5 no momento).

O código para o teste de thread que estou usando é o seguinte:

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 você executar isso com uma JVM 1.4, ela será interrompida quando não puder criar mais threads e precisar de um kill -9 (pelo menos para mim).

Mais Editar:

Acontece que o sistema que está tendo o problema está usando o modelo de encadeamento LinuxThreads, enquanto outro sistema que funciona bem está usando o modelo NPTL.

questionAnswers(5)

yourAnswerToTheQuestion