Berapa banyak utas yang dapat didukung Java VM?


212

Berapa banyak utas yang dapat didukung Java VM? Apakah ini berbeda di setiap vendor? dengan sistem operasi? faktor lain?

Jawaban:


170

Ini tergantung pada CPU yang Anda gunakan, pada OS, pada proses apa yang dilakukan, pada rilis Java apa yang Anda gunakan, dan faktor lainnya. Saya telah melihat server Windows memiliki> 6500 Threads sebelum menjatuhkan mesin. Sebagian besar utas tidak melakukan apa-apa, tentu saja. Setelah mesin mencapai sekitar 6500 Threads (di Jawa), seluruh mesin mulai mengalami masalah dan menjadi tidak stabil.

Pengalaman saya menunjukkan bahwa Java (versi terbaru) dapat dengan senang hati mengkonsumsi sebanyak Threads yang dapat dihosting oleh komputer itu sendiri tanpa masalah.

Tentu saja, Anda harus memiliki RAM yang cukup dan Anda harus memulai Java dengan memori yang cukup untuk melakukan semua yang dilakukan Threads dan memiliki tumpukan untuk setiap Thread. Mesin apa pun dengan CPU modern (generasi AMD atau Intel generasi terbaru) dan dengan memori 1 - 2 Gig (tergantung OS) dapat dengan mudah mendukung JVM dengan ribuan Thread.

Jika Anda membutuhkan jawaban yang lebih spesifik dari ini, taruhan terbaik Anda adalah profil.


86

Um, banyak.

Ada beberapa parameter di sini. VM spesifik, ditambah biasanya ada parameter run-time pada VM juga. Itu agak didorong oleh sistem operasi: dukungan apa yang dimiliki OS yang mendasarinya untuk utas dan batasan apa yang diberikan padanya? Jika VM benar-benar menggunakan utas level-OS sama sekali, utas benang merah / hijau tua yang bagus.

Apa yang dimaksud "dukungan" adalah pertanyaan lain. Jika Anda menulis program Java, itu seperti sesuatu

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(dan jangan mengeluh tentang detail sintaks yang sedikit, saya sedang minum kopi pertama saya) maka Anda tentu harus berharap untuk menjalankan ratusan atau ribuan utas. Tetapi membuat sebuah Thread relatif mahal, dan overhead scheduler bisa menjadi lebih intens; tidak jelas apakah Anda dapat meminta utas itu melakukan sesuatu yang bermanfaat.

Memperbarui

Oke, tidak bisa menahan diri. Inilah program pengujian kecil saya, dengan beberapa hiasan:

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();
        }
    }
}

Pada OS / X 10.5.6 pada Intel, dan Java 6 5 (lihat komentar), inilah yang saya dapatkan

Utas baru # 2547
Utas baru # 2548
Utas baru # 2549
Tidak dapat membuat utas: 5
Utas baru # 2550
Pengecualian di utas "utama" java.lang.OutOfMemoryError: tidak dapat membuat utas asli baru
        di java.lang.Thread.start0 (Metode Asli)
        di java.lang.Thread.start (Thread.java#92)
        di DieLikeADog.main (DieLikeADog.java:6)

10
Berapa banyak memori yang Anda mulai dengan JVM? Itu penting.
Eddie

10
Java 6 memperbarui 13, Ubuntu 8.10 32 Bit, ram 4Gig, pengaturan JVM default = 6318 Utas.
Steve K

9
Heh, mainkan dengan ukuran stack thread. java -Xss100k memungkinkan saya untuk membuat 19702 utas di Linux.
Steve K

21
java -Xss50k memberi saya sekitar 32k utas. Itu melebihi 4gigs ram saya. Saya harus menghentikan beberapa proses yang berjalan untuk mendapatkan memori yang cukup pada mesin saya untuk melakukan proses baru untuk mematikan java;) - waktu yang baik.
Steve K

21
Menggunakan Java 7 di windows 7 Saya baru saja membuat 200.000 utas sebelum sistem saya mati. Tasks Manager menunjukkan proses menggunakan 8GB RAM. Tidak yakin mengapa itu berhenti di sana, meskipun ... Saya memiliki RAM 12GB di komputer saya. Jadi ini mungkin mencapai batas lainnya.
Dobes Vandermeer

50

Setelah membaca posting Charlie Martin, saya ingin tahu apakah ukuran tumpukan membuat perbedaan dalam jumlah utas yang dapat Anda buat, dan saya benar-benar tercengang oleh hasilnya.

Menggunakan JDK 1.6.0_11 pada Vista Home Premium SP1, saya menjalankan aplikasi uji Charlie dengan berbagai ukuran tumpukan, antara 2 MB dan 1024 MB.

Sebagai contoh, untuk membuat heap 2 MB, saya akan memanggil JVM dengan argumen -Xms2m -Xmx2m.

Inilah hasil saya:

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

Jadi, ya, ukuran tumpukan pasti penting. Tetapi hubungan antara ukuran tumpukan dan jumlah utas maksimum berbanding terbalik secara proporsional.

Aneh sekali.


11
akan masuk akal jika SETIAP utas diberi tumpukan sebesar itu.
Thorbjørn Ravn Andersen

1
Peringatan: mesin saya tidak memiliki 2583 GB RAM. Atau bertukar. Dan JVM tidak mengalokasikan ruang heap thread-lokal. Sehingga tidak bisa itu ...
benjismith

49
Ukuran tumpukan mengurangi ruang alamat yang tersedia untuk tumpukan. Ruang alamat 256K / stack masuk akal.
Tom Hawtin - tackline

1
Aye, ini menunjukkan hal yang sama pequenoperro.blogspot.com/2009/02/less-is-more.html
Toby

39

Saya tahu pertanyaan ini cukup lama tetapi hanya ingin membagikan temuan saya.

Laptop saya dapat menangani program yang menumbuhkan 25,000utas dan semua utas tersebut menulis beberapa data dalam basis data MySql dengan interval reguler 2 detik.

Saya menjalankan program ini 10,000 threadsuntuk 30 minutes continuouslykemudian sistem saya stabil dan saya dapat melakukan operasi normal lainnya seperti browsing, membuka, menutup program lain, dll.

Dengan 25,000 threadssistem slows downtetapi tetap responsif.

Dengan 50,000 threadssistem secara stopped respondinginstan dan saya harus me-restart sistem saya secara manual.

Detail sistem saya adalah sebagai berikut:

Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6

Sebelum menjalankan saya mengatur argumen jvm -Xmx2048m.

Semoga ini bisa membantu.


2
"Melambat" terdengar seperti bertukar.
Thorbjørn Ravn Andersen

Terima kasih. Itu mesin yang cukup solid dan bekerja dengan baik selama hampir 8 tahun sampai tiba-tiba berhenti booting. Saya baru saja menginstal Ubuntu di atasnya, bukan Windows dan mulai angka lagi :)
Shekhar

Duo inti goreng 2 dengan bumbu ubuntu: D
Pasupathi Rajamanickam

31

The maksimum teoritis mutlak umumnya merupakan proses yang ruang alamat pengguna dibagi dengan ukuran benang tumpukan (meskipun pada kenyataannya, jika semua memori Anda dicadangkan untuk tumpukan benang, Anda tidak akan memiliki program kerja ...).

Jadi di bawah Windows 32-bit, misalnya, di mana setiap proses memiliki ruang alamat pengguna 2GB, memberikan masing-masing thread ukuran stack 128K, Anda akan mengharapkan maksimum absolut 16384 utas (= 2 * 1024 * 1024/128). Dalam praktiknya, saya menemukan saya dapat memulai sekitar 13.000 di bawah XP.

Kemudian, saya pikir Anda pada dasarnya ke apakah (a) Anda dapat mengelola juggling yang banyak thread dalam kode Anda dan tidak melakukan hal-hal yang jelas konyol (seperti membuat mereka semua menunggu pada objek yang sama kemudian memanggil notifyAll () ...), dan (b) apakah sistem operasi dapat. Pada prinsipnya, jawaban untuk (b) adalah "ya" jika jawaban untuk (a) juga "ya".

Secara kebetulan, Anda dapat menentukan ukuran tumpukan di konstruktor Thread ; Anda tidak perlu (dan mungkin tidak seharusnya) mengacaukan dengan parameter VM untuk ini.


1
Jadi gunakan OS 64-bit. Berapa lama kita semua menggunakan prosesor 64-bit untuk saat ini?
Tom Hawtin - tackline

Tentu, saya hanya memberikan contoh batasan teoritis vs praktis. Pikiran Anda, ada banyak sekali mesin 32-bit (termasuk server) masih di luar sana ...
Neil Coffey

2

Saya ingat pernah mendengar ceramah Clojure di mana ia harus menjalankan salah satu aplikasinya pada beberapa mesin khusus di sebuah pameran dagang dengan ribuan core (9000?), Dan itu memuat semuanya. Sayangnya, saya tidak dapat menemukan tautannya sekarang (bantuan?).

Berdasarkan itu, saya pikir aman untuk mengatakan bahwa perangkat keras dan kode Anda adalah faktor pembatas, bukan JVM.


bisakah kamu melihat lagi? Saya ingin melihatnya - kedengarannya menarik dan mendukung bahwa bahasa fungsional mudah untuk diukur lintas core.
Thorbjørn Ravn Andersen

Bisakah Anda memberikan tautan ke sana? Saya tahu bahwa Cliff Click, Jr., Engineer Utama dari Azul Systems menjalankan Simulasi Ant Colony Rich Hickey pada sistem JCA terbesar Azul (Azul Vega 3 Seri 7300 Model 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) dengan 864 core dan 768 core RAM GB, dan 700 semut berhasil memaksimalkan 700 core. Tapi 9000 core, itu cukup mengesankan. Mesin macam apa itu?
Jörg W Mittag

Itu adalah simulasi "Semut" yang saya percaya - inilah tautan tempat Rich Hickey (pembuat Clojure) membicarakan hal ini - blip.tv/clojure/clojure-concurrency-819147 . Itu pada beberapa kotak sistem Azul besar dengan 800 inti, terutama dilakukan untuk menunjukkan seberapa baik Clojure dalam menangani multi-core concurrency.
mikera

@mikera lins telah kedaluwarsa.
Thorbjørn Ravn Andersen

2

Setelah bermain-main dengan kelas DieLikeACode Charlie, sepertinya ukuran tumpukan ulir Java adalah bagian besar dari berapa banyak utas yang dapat Anda buat.

-Xss mengatur ukuran tumpukan thread java

Sebagai contoh

java -Xss100k DieLikeADog

Tapi, Java memiliki antarmuka Executor . Saya akan menggunakannya, Anda akan dapat mengirimkan ribuan tugas Runnable, dan meminta Pelaksana memproses tugas-tugas itu dengan sejumlah utas.


13
Bisakah kita beri nama DieLikeACat? itu tidak akan mati atau hidup sampai Anda menjalankannya.
Goodwine

Terima kasih telah menunjuk ke Executors, orang harus menggunakannya lebih sering. Tapi itu tidak akan bekerja jika Runnable/ Callablebenar-benar perlu untuk terus berjalan, seperti ketika harus menangani komunikasi. Tapi itu sempurna untuk query SQL.
Matthieu


0

Jumlah utas maksimum tergantung pada hal-hal berikut:

  • Konfigurasi Perangkat Keras seperti mikroprosesor, RAM.
  • Sistem Operasi suka apakah itu 32-bit atau 64-bit
  • Kode di dalam metode jalankan. Jika kode di dalam metode run sangat besar maka objek thread tunggal akan memiliki lebih banyak kebutuhan memori

  • 0

    Informasi tambahan untuk sistem linux modern (systemd).

    Ada banyak sumber daya tentang nilai-nilai ini yang mungkin perlu diubah (seperti Cara meningkatkan jumlah utas JVM (Linux 64bit) ); namun batas baru diberlakukan melalui batas systemd "TasksMax" yang menetapkan pids.max pada cgroup.

    Untuk sesi login, standar UserTasksMax adalah 33% dari batas kernel pids_max (biasanya 12.288) dan dapat diganti di /etc/systemd/logind.conf.

    Untuk layanan, DefaultTasksMax default adalah 15% dari pids_max batas kernel (biasanya 4,915). Anda dapat menimpanya untuk layanan dengan mengatur TasksMax di "systemctl edit" atau memperbarui DefaultTasksMax di /etc/systemd/system.conf


    0

    Tahun 2017 ... Kelas DieLikeADog.

    Utas baru # 92459 Pengecualian di utas "main" java.lang.OutOfMemoryError: tidak dapat membuat utas asli baru

    i7-7700 ram 16 GB


    Jawaban offcourse akan bervariasi. Saya mendapat 10278 dengan ram 6 GB.
    jamie

    -4

    Anda dapat memproses sejumlah utas; tidak ada batasan. Saya menjalankan kode berikut sambil menonton film dan menggunakan NetBeans, dan itu berfungsi dengan baik / tanpa menghentikan mesin. Saya pikir Anda dapat menyimpan lebih banyak utas daripada program ini.

    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
    Saya tahu ini adalah komentar yang sangat terlambat tetapi saya percaya alasan Anda dapat memulai dan menjalankan banyak utas ini adalah karena (dengan asumsi konfigurasi sistem normal dan masuk akal) setiap utas pada dasarnya mencetak satu baris dari output dan kemudian tidak memiliki alasan lagi untuk ada dan dibunuh segera setelah itu, sehingga memastikan ketersediaan sumber daya yang berkelanjutan.
    ucsunil

    @ucsunil Itu tidak benar. Saya pikir Anda salah membaca kode. Saya baru saja mencobanya dan berbagai utas tidak hanya mencetak baris pertama, tetapi juga nama mereka. Yang berarti mereka aktif. Jika Anda berpikir bahwa pengumpulan sampah akan mendaur ulang utas yang tidak direferensikan, itu tidak, lihat di sini .
    Evgeni Sergeev

    1
    Namun, setelah beberapa saat, mainakan melempar OutOfMemoryErrorpada mesin saya, mengatakan bahwa itu tidak dapat membuat utas lagi. Mungkin @AnilPal, Anda tidak menyadarinya. Saya menyarankan untuk menyertakan pernyataan cetak lain dalam main(..)metode ini, untuk melihat dengan jelas kapan ia berhenti membuat utas baru setelah melempar kesalahan.
    Evgeni Sergeev

    5
    luar biasa ... penemuan mesin Turing yang sebenarnya ... sumber daya tak terbatas.
    Josh
    Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
    Licensed under cc by-sa 3.0 with attribution required.