Низкий лимит потоков одного процесса Java в Red Hat Linux

StackOverflow https://stackoverflow.com/questions/116640

  •  02-07-2019
  •  | 
  •  

Вопрос

У меня возникла проблема на тестовой машине под управлением Red Hat Linux (версия ядра 2.4.21-37.ELsmp) с использованием Java 1.6 (1.6.0_02 или 1.6.0_04).Проблема в том, что как только в одной группе потоков создается определенное количество потоков, операционная система не желает или не может создавать больше.

Похоже, это специфично для Java, создающего потоки, поскольку программа ограничения потоков C могла создавать около 1,5 тыс. потоков.Кроме того, этого не происходит с JVM Java 1.4...он может создавать более 1,4 тыс. потоков, хотя они, очевидно, обрабатываются по-разному в зависимости от ОС.

В этом случае количество обрезаемых потоков составляет всего 29 потоков.Это можно проверить с помощью простой программы Java, которая просто создает потоки до тех пор, пока не получит ошибку, а затем печатает количество созданных потоков.Ошибка представляет собой

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

Кажется, на это не влияют такие вещи, как количество потоков, используемых другими процессами или пользователями, или общий объем памяти, который система использует в данный момент.Настройки JVM, такие как Xms, Xmx и Xss, похоже, тоже ничего не меняют (что и ожидалось, учитывая, что проблема, по-видимому, связана с созданием собственных потоков ОС).

Вывод «ulimit -a» выглядит следующим образом:

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

Ограничение пользовательского процесса, похоже, не является проблемой.Поиск информации о том, что может быть не так, особых результатов не дал, но эта почта кажется, указывает на то, что по крайней мере некоторые ядра Red Hat ограничивают процесс 300 МБ памяти, выделенной для стека, а при 10 МБ на поток для стека кажется, что проблема может быть именно здесь (хотя это также кажется странным и маловероятным).

Я попытался изменить размер стека с помощью «ulimit -s», чтобы проверить это, но любое значение, кроме 10240, и JVM не запускается с ошибкой:

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

В целом я могу обойти Linux, но на самом деле я мало что знаю о настройке системы, и мне не удалось найти ничего, что конкретно подходило бы для такого рода ситуаций.Будем признательны за любые идеи о том, какие настройки системы или JVM могут быть причиной этого.

Правки:Запуск программы ограничения потоков, упомянутой постамент, сбоя не было, пока он не попытался создать 1529-й поток.

Проблема также не возникала при использовании JVM 1.4 (проблема возникает с JVM 1.6.0_02 и 1.6.0_04, на данный момент невозможно протестировать JVM 1.5).

Код для теста потока, который я использую, выглядит следующим образом:

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) {
         }
      }
   }
}

Если вы запустите это с помощью JVM 1.4, оно зависнет, когда не сможет создавать больше потоков, и потребует уничтожения -9 (по крайней мере, так было у меня).

Больше редактирования:

Оказывается, что система, в которой возникла проблема, использует модель потоков LinuxThreads, а другая система, которая работает нормально, использует модель NPTL.

Это было полезно?

Решение 2

Обновление ядра до более новой версии (2.6.что-то) с многопоточностью NPTL исправило это.

Другие советы

Вы посмотрели этот ресурс?В нем говорится, что вы должны иметь возможность запускать thread-limit, чтобы найти максимальное количество потоков, и можете настроить его, скомпилировав glibc.

Это с Ubuntu Linux (1 ГБ ОЗУ)

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:~$ 

Можете ли вы попробовать это с JRockit JVM?IIRC, у него была другая модель потоков, чем у стандартной Sun JVM.

Настройки в /etc/security/limits.d/90-nproc.conf может быть переопределяет ваш /etc/security/limits.conf настройки.Это может привести к тому, что система будет действовать по-другому, как показано на рис. ulimit -u.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top