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


212

Скільки потоків може підтримувати Java VM? Чи залежить це від постачальника? операційною системою? інші фактори?

Відповіді:


170

Це залежить від CPU, який ви використовуєте, в ОС, від того, які інші процеси виконуються, від того, який випуск Java ви використовуєте, та інших факторів. Я бачив, як сервер Windows має> 6500 ниток перед тим, як збити машину. Більшість ниток, звичайно, нічого не робили. Після того, як машина потрапила близько 6500 ниток (на Java), у всієї машини почалися проблеми і стали нестабільними.

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

Звичайно, у вас має бути достатньо оперативної пам’яті, і ви повинні запустити Java з достатньою пам’яттю, щоб зробити все, що нитки роблять, і мати стек для кожної теми. Будь-яка машина із сучасним процесором (останні пару поколінь AMD чи Intel) та 1–2 гіга пам’яті (залежно від ОС) може легко підтримувати JVM з тисячами ниток.

Якщо вам потрібна більш конкретна відповідь, ніж ця, найкраще зробити ваш профіль.


86

Гм, багато.

Тут є кілька параметрів. Конкретний VM, а також зазвичай є параметри часу роботи на VM. Це дещо керується операційною системою: яку підтримку має основна ОС для потоків і які обмеження вона накладає на них? Якщо VM насправді взагалі використовує нитки рівня ОС, стара хороша червона нитка / зелена нитка.

Що означає "підтримка" - це інше питання. Якщо ви пишете програму 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();
        }
    }
}

У ОС / X 10.5.6 на Intel та Java 6 5 (див. Коментарі), ось що я отримав

Нова тема # 2547
Нова тема # 2548
Нова тема # 2549
Неможливо створити потік: 5
Нова тема # 2550
Виняток у потоці "main" java.lang.OutOfMemoryError: не вдається створити нову рідну нитку
        at java.lang.Thread.start0 (Рідний метод)
        у java.lang.Thread.start (Thread.javajanju92)
        на DieLikeADog.main (DieLikeADog.java:6)

10
Скільки пам’яті ви запустили JVM? Це має значення.
Едді

10
Оновлення Java 6 13, Ubuntu 8.10 32 біт, 4Gig оперативної пам'яті, параметри JVM за замовчуванням = 6318 Теми.
Стів К

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

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

21
Використовуючи Java 7 у Windows 7, я щойно створив 200 000 ниток до моєї системи. Диспетчер завдань показав процес, використовуючи 8 ГБ оперативної пам’яті. Не впевнений, чому він там зупинився, хоча ... У мене на комп’ютері є 12 Гб оперативної пам’яті. Тож це може бути певною межею.
Dobes Vandermeer

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
Було б сенс, якби кожній нитці надавали купу такого розміру.
Thorbjørn Ravn Andersen

1
Caveat: у моєї машини немає 2583 ГБ оперативної пам’яті. Або поміняти місцями. І JVM не виділяє місцевих потоків купи місце. Так що не може бути ...
benjismith

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

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
"Уповільнює" звук як обмін.
Thorbjørn Ravn Andersen

Дякую. Це була досить міцна машина і працювала прекрасно майже 8 років, поки раптом вона не перестала завантажуватися. Я щойно встановив Ubuntu на ньому замість Windows, і він знову почав стискати номери :)
Shekhar

Дует смаженого ядра 2 з приправою ubuntu: D
Pasupathi Rajamanickam

31

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

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

Тоді, я думаю, ви по суті вирішите, чи (а) ви можете керувати жонглюванням багатьма потоками у своєму коді, а не робити очевидно дурних речей (наприклад, змусити їх усіх чекати на одному об’єкті, а потім викликати notifyAll () ...), та (b) чи може операційна система. В принципі, відповідь на (b) - "так", якщо відповідь на (a) також "так".

Між іншим, ви можете вказати розмір стека в конструкторі Thread ; для цього вам не потрібно (і, мабуть, не варто) возитися з параметрами VM.


1
Тому використовуйте 64-бітну ОС. Як довго ми всі зараз використовуємо 64-бітні процесори?
Том Хотін - тайклін

Звичайно, я лише навожу приклад теоретичного та практичного обмеження. Зверніть увагу, там ще дуже багато 32-розрядних машин (включаючи сервери) ...
Neil Coffey

2

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

Виходячи з цього, я думаю, що можна з упевненістю сказати, що обладнання та ваш код є обмежуючими факторами, а не JVM.


ти міг би знову подивитися? Мені б хотілося це побачити - це звучить цікаво і підтверджує, що функціональні мови легко масштабувати по ядрах.
Thorbjørn Ravn Andersen

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

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

Термін дії @mikera закінчився.
Thorbjørn Ravn Andersen

2

Після розігрування з класом DieLikeACode Чарлі, схоже, розмір стека потоку Java є величезною частиною кількості потоків, які ви можете створити.

-Xss встановити розмір стеки Java-нитки

Наприклад

java -Xss100k DieLikeADog

Але у Java є інтерфейс Executor . Я б використав це, ви зможете подати тисячі завдань, що виконується, і Виконавець виконає ці завдання з фіксованою кількістю потоків.


13
Чи можемо ми назвати його DieLikeACat? вона не буде ні мертвою, ні живою, поки не запустите її.
Goodwine

Дякуємо, що вказували на Виконавців, люди повинні використовувати це частіше. Але це не спрацює, якщо Runnable/ Callableнасправді потрібно працювати постійно, як, наприклад, коли він має працювати з комунікацією. Але він ідеально підходить для запитів SQL.
Матьє


0

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

  • Конфігурація обладнання, наприклад мікропроцесор, оперативна пам'ять.
  • Операційна система, як-от 32-розрядна чи 64-розрядна
  • Код всередині методу запуску. Якщо код у методі запуску величезний, то для одного об’єкта буде потрібна більше пам'яті

  • 0

    Додаткова інформація про сучасні (systemd) системи Linux.

    Є багато ресурсів щодо цього значень, які можуть потребувати налаштування (наприклад, як збільшити максимальну кількість потоків JVM (Linux 64bit) ); однак новий ліміт накладається через системний ліміт "TasksMax", який встановлює pids.max на cgroup.

    Для сеансів входу за замовчуванням UserTasksMax становить 33% від обмеження ядра pids_max (зазвичай 12,288) і може бути замінено в /etc/systemd/logind.conf.

    Для служб за замовчуванням DefaultTasksMax становить 15% від обмеження ядра pids_max (зазвичай 4 915). Ви можете змінити його для служби, встановивши 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(..)метод, щоб чітко побачити, коли він перестає створювати нові теми після викидання помилки.
    Євгеній Сергєєв

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