У меня возникла проблема на тестовом компьютере под управлением 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.