У меня возникла проблема на тестовой машине с Red Hat Linux (версия ядра 2.4.21-37.ELsmp) с Java 1.6 (1.6.0_02 или 1.6.0_04). Проблема в том, что как только определенное количество потоков создается в одной группе потоков, операционная система не желает или не может создавать больше.
Кажется, это характерно для Java, создающего потоки, поскольку программа ограничения потоков C смогла создать около 1,5 тыс. Потоков. Кроме того, этого не происходит с Java 1.4 JVM ... она может создавать более 1,4 тыс. Потоков, хотя, очевидно, они обрабатываются по-разному в зависимости от ОС.
In this case, the number of threads it's cutting off at is a mere 29 threads. This is testable with a simple Java program that just creates threads until it gets an error and then prints the number of threads it created. The error is a
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.
while(true)
нигде, кроме школьных проектов и частных экспериментов, и НИКОГДА не создавайте тысячи потоков, в вашем приложении, скорее всего, есть серьезные ошибки, если они есть - в противном случае дизайн вашего приложения ошибочен. Просто говорю .. - person specializt   schedule 16.01.2015