В большинстве операционных систем стек распределяется лениво, то есть только те страницы, которые вы фактически используете, превращаются в реальную память. Ваш процесс ограничен от 128 до 256 ТБ виртуальной памяти на процесс, в зависимости от используемой ОС, поэтому при 1 ГБ на поток вам нужно как минимум 128 КБ потоков. Я бы попробовал намного больший стек. Например. 256g
РЕДАКТИРОВАТЬ: Попробовать это сам, похоже, он игнорирует размеры стека 4g и выше. Самый большой размер -Xss4000m на окнах.
Попытка воспроизвести это в Windows, и кажется, что она перегружает машину до того, как возникнет какое-либо исключение.
Это то, что я пытался. Запустив -Xss4000m
, он получил более 20 потоков (всего 80 г, прежде чем мой ноутбук с Windows перестал работать)
Вы можете найти в Linux, что он достигнет ulimit
перед перегрузкой машины.
import java.util.concurrent.*;
class A {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor pool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<>());
try {
for (int i = 0; i < 100; i++) {
System.out.println(i);
pool.submit(() -> {
try {
System.out.println(recurse() + " size " + pool.getPoolSize());
} catch (Throwable t) {
t.printStackTrace();
}
return null;
});
Thread.sleep(1000);
}
} finally {
pool.shutdown();
}
}
static long recurse() {
try {
return 1 + recurse();
} catch (Error e) {
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return 1;
}
}
}