Сколько потоков может поддерживать Java VM? Это зависит от поставщика? по операционной системе? другие факторы?
Сколько потоков может поддерживать Java VM? Это зависит от поставщика? по операционной системе? другие факторы?
Ответы:
Это зависит от процессора, который вы используете, от операционной системы, от того, что делают другие процессы, от того, какую версию Java вы используете, и от других факторов. Я видел, что сервер Windows имеет> 6500 потоков, прежде чем выключить машину. Конечно, большинство потоков ничего не делали. Как только машина набрала около 6500 потоков (на Java), у всей машины начались проблемы и она стала нестабильной.
Мой опыт показывает, что Java (последние версии) может с удовольствием потреблять столько потоков, сколько сам компьютер может разместить без проблем.
Конечно, у вас должно быть достаточно оперативной памяти, и вы должны запустить Java с достаточным объемом памяти, чтобы делать все, что делают потоки, и иметь стек для каждого потока. Любая машина с современным процессором (последние пару поколений AMD или Intel) и с 1–2 гигабайтами памяти (в зависимости от ОС) может легко поддерживать JVM с тысячами потоков.
Если вам нужен более конкретный ответ, чем этот, лучше всего подать заявку.
Хм, много.
Здесь есть несколько параметров. Определенная виртуальная машина, плюс, как правило, на ней также есть параметры времени выполнения. Это в некоторой степени определяется операционной системой: какую поддержку имеет базовая ОС для потоков и какие ограничения она на них накладывает? Если виртуальная машина вообще использует потоки уровня ОС, то старый добрый красный / зеленый поток.
Что означает «поддержка» - это другой вопрос. Если вы пишете программу на Java, это просто что-то вроде
class DieLikeADog {
public static void main(String[] argv){
for(;;){
new Thread(new SomeRunaable).start();
}
}
}
(и не жалуйтесь на мелкие детали синтаксиса, я нахожусь на моей первой чашке кофе), тогда вы наверняка должны ожидать запуска сотен или тысяч потоков. Но создание потока относительно дорого, и затраты на планировщик могут быть очень интенсивными; неясно, что вы могли бы сделать эти темы сделать что-нибудь полезное.
Ладно, не удержался. Вот моя маленькая тестовая программа с парой украшений:
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 (см. Комментарии) вот что я получил
Новая тема # 2547 Новая тема № 2548 Новая тема # 2549 Не могу создать тему: 5 Новая тема # 2550 Исключение в потоке "main" java.lang.OutOfMemoryError: невозможно создать новый собственный поток на java.lang.Thread.start0 (собственный метод) на java.lang.Thread.start (Thread.java:592) в DieLikeADog.main (DieLikeADog.java:6)
Прочитав статью Чарли Мартина, мне стало интересно, влияет ли размер кучи на количество потоков, которые вы можете создать, и я был совершенно ошеломлен результатом.
Используя JDK 1.6.0_11 в Vista Home Premium SP1, я выполнил тестовое приложение Чарли с разными размерами кучи, от 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
Так что, да, размер кучи определенно имеет значение. Но взаимосвязь между размером кучи и максимальным количеством потоков Неверно пропорциональна.
Что странно.
Я знаю, что этот вопрос довольно старый, но просто хочу поделиться своими выводами.
Мой ноутбук может работать с программой, которая порождает 25,000
потоки, и все эти потоки записывают некоторые данные в базу данных MySql с регулярным интервалом в 2 секунды.
Я запустил эту программу 10,000 threads
для 30 minutes continuously
тогда и моя система была стабильной , и я был в состоянии сделать другие обычные операции как просмотр, открытие, закрытие других программ и т.д.
С 25,000 threads
системой, slows down
но она остается отзывчивой.
С 50,000 threads
системой stopped responding
мгновенно, и мне пришлось перезагрузить систему вручную.
Мои системные данные следующие:
Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6
Перед запуском я устанавливаю аргумент jvm -Xmx2048m
.
Надеюсь, поможет.
Абсолютный теоретический максимум , как правило , процесс , в адресном пространстве пользователя делится на размер стека потока (хотя на самом деле, если вся ваша память резервируется для стеков потоков, вы не будете иметь рабочую программу ...).
Так, например, в 32-битной Windows, где каждый процесс имеет адресное пространство пользователя 2 ГБ, что дает каждому потоку размер стека 128 КБ, можно ожидать абсолютного максимума в 16384 потока (= 2 * 1024 * 1024/128). На практике я могу запустить около 13000 под XP.
Затем, я думаю, вы по существу в том, что (а) вы можете управлять жонглированием таким количеством потоков в вашем коде и не делать явно глупых вещей (например, заставить их всех ждать одного и того же объекта, а затем вызывать notifyAll () ...), и (b) может ли операционная система. В принципе, ответом на (б) является «да», если ответом на (а) также является «да».
Кстати, вы можете указать размер стека в конструкторе Thread ; для этого вам не нужно (и, вероятно, не следует) возиться с параметрами виртуальной машины.
Я помню, как слышал лекцию Clojure, в которой он запустил одно из своих приложений на каком-то специализированном компьютере на выставке с тысячами ядер (9000?), И они загрузили их все. К сожалению, я не могу найти ссылку прямо сейчас (помощь?).
Исходя из этого, я думаю, можно с уверенностью сказать, что аппаратные средства и ваш код являются ограничивающими факторами, а не JVM.
Поиграв с классом Чарли DieLikeACode, похоже, что размер стека потоков Java - огромная часть того, сколько потоков вы можете создать.
-Xss установить размер стека Java-потока
Например
java -Xss100k DieLikeADog
Но у Java есть интерфейс Executor . Я хотел бы использовать это, вы сможете отправить тысячи задач Runnable, и исполнитель будет обрабатывать эти задачи с фиксированным числом потоков.
Runnable
/ Callable
действительно нужно работать непрерывно, например, когда он должен обрабатывать связь. Но он идеально подходит для запросов SQL.
По крайней мере, в Mac OS X 10.6 32bit существует ограничение (2560) для операционной системы. Проверьте этот поток stackoverflow .
Дополнительная информация для современных (systemd) систем Linux.
Есть много ресурсов об этом значениях, которые могут нуждаться в настройке (например, Как увеличить максимальное количество потоков JVM (Linux 64bit) ); однако новый лимит накладывается посредством лимита systemd "TasksMax", который устанавливает pids.max для cgroup.
Для сеансов входа в систему значение UserTasksMax по умолчанию составляет 33% от ограничения ядра pids_max (обычно 12 288) и может быть переопределено в /etc/systemd/logind.conf.
Для сервисов DefaultTasksMax по умолчанию составляет 15% от лимита ядра pids_max (обычно 4915). Вы можете переопределить его для службы, установив TasksMax в «systemctl edit» или обновив DefaultTasksMax в /etc/systemd/system.conf
Вы можете обрабатывать любое количество потоков; нет предела. Я запускал следующий код во время просмотра фильма и использования 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();
}
}
}
main
появится сообщение OutOfMemoryError
о том, что он не может создавать больше потоков. Возможно @AnilPal, вы этого не заметили. Я предлагаю включить в main(..)
метод еще один оператор print , чтобы ясно видеть, когда он прекращает создавать новые потоки после выдачи ошибки.