Низкое ограничение потока одного процесса Java в Red Hat Linux - PullRequest
7 голосов
/ 22 сентября 2008

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

Это, кажется, характерно для создания потоков в Java, так как программа C-limit-limit смогла создать около 1,5 тыс. Потоков. Кроме того, этого не происходит с Java 1.4 JVM ... он может создавать более 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, в настоящее время невозможно выполнить тестирование с 1.5 JVM).

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

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

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

Подробнее Редактировать:

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

Ответы [ 5 ]

4 голосов
/ 04 октября 2008

Обновление ядра до более новой версии (2.6.something) с поддержкой потоков NPTL исправило это.

4 голосов
/ 22 сентября 2008

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

0 голосов
/ 22 августа 2016

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

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

0 голосов
/ 23 сентября 2008

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

0 голосов
/ 23 сентября 2008

Это с 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:~$ 
...