Сколько потоков может поддерживать 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

Ответ 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();
        }
    }
}