Сколько потоков может поддерживать Java VM? Это зависит от поставщика? операционной системой? другие факторы?
Сколько потоков может поддерживать Java VM?
Ответ 1
Это зависит от используемого вами процессора, от ОС, от того, что делают другие процессы, от того, какую версию Java вы используете, и других факторов. Я видел, как на сервере Windows было > 6500 потоков, прежде чем приводить машину в порядок. Конечно, большинство нитей ничего не делали. Как только машина обрушилась на 6500 потоков (на Java), вся машина начала испытывать проблемы и стала нестабильной.
Мой опыт показывает, что Java (последние версии) могут радостно потреблять столько потоков, сколько сам компьютер может без проблем работать.
Конечно, у вас должно быть достаточно ОЗУ, и вы должны запустили Java с достаточной памятью, чтобы делать все, что делают Threads, и иметь стек для каждого потока. Любая машина с современным процессором (последние несколько поколений AMD или Intel) и с 1 - 2 гигабайтами памяти (в зависимости от ОС) может легко поддерживать JVM с тысячами потоков.
Если вам нужен более конкретный ответ, чем это, лучше всего настроить профиль.
Ответ 2
Ум, много.
Здесь есть несколько параметров. Конкретная виртуальная машина, а также, как правило, есть параметры времени выполнения на виртуальной машине. Это несколько обусловлено операционной системой: какая поддержка делает базовая ОС для потоков и какие ограничения она накладывает на них? Если виртуальная машина фактически использует потоки уровня ОС на всех, хорошая старая красная нить/зеленая нить.
Что означает "поддержка", это другой вопрос. Если вы пишете Java-программу, которая просто похожа на
class DieLikeADog {
public static void main(String[] argv){
for(;;){
new Thread(new SomeRunaable).start();
}
}
}
(и не жалуйтесь на небольшие подробности синтаксиса, я нахожусь на своей первой чашке кофе), тогда вы наверняка должны ожидать, что сотни или тысячи потоков будут работать. Но создание Thread относительно дорого, и накладные расходы планировщика могут стать интенсивными; неясно, что вы могли бы сделать эти потоки полезными.
Update
Хорошо, не мог устоять. Здесь моя небольшая тестовая программа с двумя украшениями:
public class DieLikeADog {
private static Object s = new Object();
private static int count = 0;
public static void main(String[] argv){
for(;;){
new Thread(new Runnable(){
public void run(){
synchronized(s){
count += 1;
System.err.println("New thread #"+count);
}
for(;;){
try {
Thread.sleep(1000);
} catch (Exception e){
System.err.println(e);
}
}
}
}).start();
}
}
}
В OS/X 10.5.6 на Intel и Java 6 5 (см. комментарии), вот что я получил
New thread #2547 New thread #2548 New thread #2549 Can't create thread: 5 New thread #2550 Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:592) at DieLikeADog.main(DieLikeADog.java:6)
Ответ 3
После прочтения сообщения Charlie Martin мне было интересно узнать, не влияет ли размер кучи на количество потоков, которые вы можете создать, и я был полностью ошеломлен результатом.
Используя JDK 1.6.0_11 в Vista Home Premium SP1, я выполнил тестовое приложение Charlie с разными размерами кучи размером от 2 до 1024 МБ.
Например, чтобы создать кучу размером 2 МБ, я бы вызвал JVM с аргументами -Xms2m -Xmx2m.
Вот мои результаты:
2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads
Итак, да, размер кучи определенно имеет значение. Но соотношение между размером кучи и максимальным количеством потоков является ПОЛНОСТЬЮ пропорциональным.
Что странно.
Ответ 4
Я знаю, что этот вопрос довольно старый, но просто хочу поделиться своими выводами.
Мой ноутбук способен обрабатывать программу, которая порождает потоки 25,000
, и все эти потоки записывают некоторые данные в базу данных MySql с регулярным интервалом в 2 секунды.
Я запускал эту программу с помощью 10,000 threads
для 30 minutes continuously
, тогда моя система была стабильной, и я мог выполнять другие обычные операции, такие как просмотр, открытие, закрытие других программ и т.д.
С системой 25,000 threads
slows down
, но она остается отзывчивой.
С 50,000 threads
system stopped responding
мгновенно, и мне пришлось перезагрузить систему вручную.
Мои данные системы выглядят следующим образом:
Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6
Перед запуском задайте аргумент jvm -Xmx2048m
.
Надеюсь, что это поможет.
Ответ 5
Абсолютный теоретический максимум - это обычно адресное пространство пользователя, разделенное на размер стека потоков (хотя на самом деле, если вся ваша память зарезервирована для стеков потоков, вы не будет рабочей программы...).
Итак, под 32-разрядной Windows, например, где каждый процесс имеет адресное пространство пользователя 2 ГБ, каждый поток имеет размер стека размером 128 тыс., вы ожидаете абсолютный максимум 16384 потоков (= 2 * 1024 * 1024/128). На практике я нахожу, что могу запустить около 13 000 под XP.
Затем я думаю, что вы по существу в том, что (а) вы можете управлять жонглированием этим количеством потоков в своем коде и не делать явно глупых вещей (например, заставить их всех ждать на одном и том же объекте, а затем вызывать notifyAll()...) и (б) может ли операционная система. В принципе, ответ на (б) "да", если ответ на (а) также "да".
Кстати, вы можете указать размер стека в конструкторе Thread; вам не нужно (и, вероятно, не должно) путаться с параметрами VM для этого.
Ответ 6
Я помню, как слышал разговор Clojure, где он запустил одно из своих приложений на какой-то специализированной машине на выставке с тысячами ядер (9000?), и она загрузила их все. К сожалению, я не могу найти ссылку прямо сейчас (help?).
Исходя из этого, я считаю, что безопасно говорить, что аппаратное обеспечение и ваш код являются ограничивающими факторами, а не JVM.
Ответ 7
После игры с классом Charlie DieLikeACode, похоже, что размер стека Java-потоков является огромной частью того, сколько потоков вы можете создать.
-Xss устанавливает размер стека java-потока
Например
java -Xss100k DieLikeADog
Но у Java есть Executor интерфейс. Я бы использовал это, вы сможете отправить тысячи задач Runnable, и Executor обрабатывает эти задачи с фиксированным количеством потоков.
Ответ 8
Год 2017... Класс DieLikeADog.
Новый поток # 92459 Исключение в потоке "main" java.lang.OutOfMemoryError: невозможно создать новый собственный поток
i7-7700 16gb ram
Ответ 9
Ответ 10
Как минимум, на Mac OS X 10.6 32bit существует ограничение (2560) операционной системы. Проверьте этот поток потокового стека.
Ответ 11
Максимальное количество потоков зависит от следующих вещей:
Конфигурация оборудования, такая как микропроцессор, оперативная память. Операционная система, например, 32-разрядная или 64-разрядная Код внутри метода запуска. Если код внутри метода запуска огромен, то объект с одним потоком будет иметь больше требований к памятиОтвет 12
Дополнительная информация для современных (системных) Linux-систем.
В этом есть много ресурсов, которые могут нуждаться в настройке (например, Как увеличить максимальное количество потоков JVM (Linux 64bit)); однако новый предел накладывается посредством предела systemd "TasksMax", который устанавливает pids.max в группе.
Для сеансов входа значение UserTasksMax по умолчанию составляет 33% от предела ядра pids_max (обычно 12,288) и может быть переопределено в /etc/systemd/logind.conf.
Для служб DefaultTasksMax значение по умолчанию составляет 15% от предела ядра pids_max (обычно 4 915). Вы можете переопределить его для службы, установив TasksMax в "systemctl edit" или обновив DefaultTasksMax в/etc/systemd/system.conf
Ответ 13
Вы можете обрабатывать любое количество потоков; нет предела. Я запускал следующий код во время просмотра фильма и использования NetBeans, и он работал нормально/без остановки машины. Я думаю, вы можете сохранить еще больше потоков, чем это делает программа.
class A extends Thread {
public void run() {
System.out.println("**************started***************");
for(double i = 0.0; i < 500000000000000000.0; i++) {
System.gc();
System.out.println(Thread.currentThread().getName());
}
System.out.println("************************finished********************************");
}
}
public class Manager {
public static void main(String[] args) {
for(double j = 0.0; j < 50000000000.0; j++) {
A a = new A();
a.start();
}
}
}