Сколько потоков может поддерживать Java VM?


212

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

Ответы:


170

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

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

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

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


86

Хм, много.

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

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

10
Сколько памяти вы запустили JVM? Это важно
Эдди

10
Java 6, обновление 13, Ubuntu 8.10 32-битная, 4-гигабайтная оперативная память, настройки JVM по умолчанию = 6318 потоков.
Стив К

9
Хех, играйте с размером стека потоков. java -Xss100k позволил мне создавать потоки 19702 в Linux.
Стив К

21
java -Xss50k получил меня вокруг 32k потоков. Это максимизировало мои 4 гигабайта ОЗУ. Мне пришлось остановить некоторые запущенные процессы, чтобы вернуть достаточное количество памяти на мою машину, чтобы запустить новый процесс, чтобы убить Java;) - хорошие времена.
Стив К

21
Используя Java 7 на Windows 7, я только что создал 200 000 потоков, прежде чем моя система умерла. Диспетчер задач показал процесс с использованием 8 ГБ оперативной памяти. Не уверен, почему это остановилось там, хотя ... У меня 12 ГБ ОЗУ на моем компьютере. Так что это может достигать некоторого другого предела.
Добес Вандермер

50

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

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

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

Что странно.


11
будет иметь смысл, если КАЖДОМУ потоку дается куча такого размера.
Торбьерн Равн Андерсен

1
Предостережение: моя машина не имеет 2583 ГБ оперативной памяти. Или поменяй местами. И JVM не выделяет пространство кучи локального потока. Так что этого не может быть ...
Бенджизм с

49
Размер кучи уменьшает адресное пространство, доступное для стеков. Адресное пространство 256K / стек имеет смысл.
Том Хотин - tackline

1
Да, это показывает то же самое pequenoperro.blogspot.com/2009/02/less-is-more.html
Тоби

39

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

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

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


2
«Замедление» звучит как обмен.
Торбьерн Равн Андерсен

Спасибо. Это была довольно прочная машина, и она работала нормально почти 8 лет, пока внезапно перестала загружаться. Я просто установил на него Ubuntu вместо Windows, и он снова начал работать с числами :)
Shekhar

Жареный дуэт Core 2 с приправой Ubuntu: D
Pasupathi Rajamanickam

31

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

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

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

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


1
Так что используйте 64-битную ОС. Как долго мы все сейчас используем 64-битные процессоры?
Том Хотин - tackline

Конечно, я просто привожу пример теоретического и практического ограничения. Имейте в виду, есть еще 32-битные машины (включая серверы), которые все еще существуют ...
Нил Коффи

2

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

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


ты не мог бы посмотреть снова? Я хотел бы видеть это - это звучит интересно и поддерживает то, что функциональные языки легко масштабируются по ядрам.
Торбьерн Равн Андерсен

Можете ли вы предоставить ссылку на это? Я знаю, что Клифф Клик-младший, ведущий инженер Azul Systems, управлял симуляцией колонии муравьев Рича Хикки в самой большой системе JCA в Azul (Azul Vega 3-й серии 7300 модель 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) с 864 ядрами и 768 ГБ оперативной памяти, а 700 муравьям удалось максимально использовать 700 ядер. Но 9000 ядер - это впечатляет. Что это за машина?
Йорг Миттаг

Я полагаю, что это была симуляция "Муравьи" - вот ссылка, по которой об этом говорит Рич Хики (создатель Clojure) - blip.tv/clojure/clojure-concurrency-819147 . Это было на некоторых больших системах Azul с 800+ ядрами, в основном, чтобы продемонстрировать, насколько хорош Clojure для обработки многоядерного параллелизма.
Микера

Срок действия @mikera lins истек.
Турбьёрн Равн Андерсен

2

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

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

Например

java -Xss100k DieLikeADog

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


13
Можем ли мы назвать это DieLikeACat? он не будет ни мертвым, ни живым, пока вы не запустите его.
Goodwine

Спасибо за указание на исполнителей, люди должны использовать его чаще. Но это не сработает, если Runnable/ Callableдействительно нужно работать непрерывно, например, когда он должен обрабатывать связь. Но он идеально подходит для запросов SQL.
Матье


0

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

  • Конфигурация оборудования, как микропроцессор, RAM.
  • Операционная система вроде 32-битной или 64-битной
  • Код внутри метода run. Если код внутри метода run огромен, то однопоточному объекту будет требоваться больше памяти

  • 0

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

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

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

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


    Ответы, конечно же, будут разными. Я получил 10278 с 6 ГБ оперативной памяти.
    Jamie

    -4

    Вы можете обрабатывать любое количество потоков; нет предела. Я запускал следующий код во время просмотра фильма и использования 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();
            }
        }
    }

    7
    Я знаю, что это комментарий очень поздно, но я полагаю, что причина, по которой вы смогли запустить и запустить эти многочисленные потоки, заключается в том, что (при условии нормальной и разумной конфигурации системы) каждый поток в основном выводит одну строку из вывода, а затем не имеет больше причин для существует и вскоре убивается, тем самым обеспечивая постоянную доступность ресурсов.
    Ucsunil

    @ucsunil Это не правда. Я думаю, что вы неправильно прочитали код. Я только что попробовал, и различные темы распечатывают не только первую строку, но и их имена. Что означает, что они активны. Если вы думали, что сборщик мусора будет перерабатывать потоки, на которые нет ссылок, это не так, смотрите здесь .
    Евгений Сергеев

    1
    Однако через некоторое время на моем компьютере mainпоявится сообщение OutOfMemoryErrorо том, что он не может создавать больше потоков. Возможно @AnilPal, вы этого не заметили. Я предлагаю включить в main(..)метод еще один оператор print , чтобы ясно видеть, когда он прекращает создавать новые потоки после выдачи ошибки.
    Евгений Сергеев

    5
    удивительно ... открытие настоящей машины Тьюринга ... бесконечные ресурсы.
    Джош
    Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
    Licensed under cc by-sa 3.0 with attribution required.