Сколько потоков может поддерживать Java VM? - PullRequest
193 голосов
/ 18 апреля 2009

Сколько потоков может поддерживать Java VM? Это зависит от поставщика? по операционной системе? другие факторы?

Ответы [ 13 ]

157 голосов
/ 18 апреля 2009

Это зависит от процессора, который вы используете, от операционной системы, от того, что делают другие процессы, от того, какую версию Java вы используете, и от других факторов. Я видел, что сервер Windows имеет> 6500 потоков, прежде чем остановить машину. Конечно, большинство потоков ничего не делали. Как только машина достигла 6500 потоков (в Java), у всей машины возникли проблемы и она стала нестабильной.

Мой опыт показывает, что Java (последние версии) может с удовольствием использовать столько потоков, сколько сам компьютер может разместить без проблем.

Конечно, у вас должно быть достаточно ОЗУ, и вы должны запустить Java с достаточным объемом памяти, чтобы делать все, что делают потоки, и иметь стек для каждого потока. Любая машина с современным процессором (последние пару поколений AMD или Intel) и с 1–2 гигабайтами памяти (в зависимости от ОС) может легко поддерживать JVM с тысяч потоков.

Если вам нужен более конкретный ответ, чем этот, лучше всего подать заявку.

81 голосов
/ 18 апреля 2009

Хм, много.

Здесь есть несколько параметров. Определенная виртуальная машина, плюс, как правило, на ней также есть параметры времени выполнения. Это в некоторой степени определяется операционной системой: какую поддержку имеет базовая ОС для потоков и какие ограничения она на них накладывает? Если виртуальная машина вообще использует потоки уровня ОС, то старый добрый красный / зеленый поток.

Что означает «поддержка» - это другой вопрос. Если вы пишете программу на 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 (см. Комментарии) вот что я получил

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)
46 голосов
/ 18 апреля 2009

Прочитав пост Чарли Мартина, мне стало интересно, влияет ли размер кучи на количество потоков, которые вы можете создать, и я был совершенно ошеломлен результатом.

Используя 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

Так что, да, размер кучи определенно имеет значение. Но соотношение между размером кучи и максимальным числом потоков НЕВЕРНО пропорционально.

Что странно.

35 голосов
/ 21 апреля 2013

Я знаю, что этот вопрос довольно старый, но просто хочу поделиться своими выводами.

Мой ноутбук может работать с программой, которая порождает потоки 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.

Надеюсь, это поможет.

29 голосов
/ 19 апреля 2009

Абсолютный теоретический максимум - это обычно адресное пространство пользователя процесса, разделенное на размер стека потоков (хотя в действительности, если вся ваша память зарезервирована для стеков потоков, вы выиграли ' у меня есть рабочая программа ...).

Так, например, в 32-битной Windows, где каждый процесс имеет адресное пространство пользователя 2 ГБ, при этом каждый поток имеет размер стека 128 КБ, можно ожидать абсолютного максимума в 16384 потока (= 2 *1024* 1024 / 128). На практике я могу запустить около 13000 под XP.

Тогда, я думаю, вы по существу в том, можете ли (a) вы управлять жонглированием таким количеством потоков в вашем коде и не делать явно глупых вещей (например, заставить их всех ждать один и тот же объект) вызов notifyAll () ...) и (b) может ли операционная система. В принципе, ответом на (b) является «да», если ответом на (а) также является «да».

Кстати, вы можете указать размер стека в конструкторе Thread ; для этого вам не нужно (и, вероятно, не следует) возиться с параметрами виртуальной машины.

2 голосов
/ 18 апреля 2009

После игры с классом Чарли DieLikeACode кажется, что размер стека потоков Java - огромная часть того, сколько потоков вы можете создать.

-Xss установить размер стека Java-потока

Например

java -Xss100k DieLikeADog

Но в Java есть интерфейс Executor . Я хотел бы использовать это, вы сможете отправить тысячи задач Runnable, и исполнитель будет обрабатывать эти задачи с фиксированным числом потоков.

2 голосов
/ 18 апреля 2009

Я вспоминаю, как слышал лекцию Clojure, на которой он запустил одно из своих приложений на каком-то специализированном компьютере на выставке с тысячами ядер (9000?), И он загрузил их все. К сожалению, сейчас я не могу найти ссылку (справка?).

Исходя из этого, я думаю, можно с уверенностью сказать, что аппаратные средства и ваш код являются ограничивающими факторами, а не JVM.

0 голосов
/ 11 октября 2017

год 2017 ... Класс DieLikeADog.

Новая тема # 92459 Исключение в потоке "main" java.lang.OutOfMemoryError: невозможно создать новый собственный поток

i7-7700 16 ГБ оперативной памяти

0 голосов
/ 01 апреля 2017

Дополнительная информация для современных (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

0 голосов
/ 29 мая 2013

Максимальное количество потоков зависит от следующих вещей:

Конфигурация оборудования, например, микропроцессор, ОЗУ. Операционная система, как 32-битная или 64-битная Код внутри метода run. Если код внутри метода run огромен, то для однопоточного объекта будет требоваться больше памяти
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...