Berapa banyak utas yang dapat didukung Java VM? Apakah ini berbeda di setiap vendor? dengan sistem operasi? faktor lain?
Berapa banyak utas yang dapat didukung Java VM? Apakah ini berbeda di setiap vendor? dengan sistem operasi? faktor lain?
Jawaban:
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.
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.
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)
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.
Saya tahu pertanyaan ini cukup lama tetapi hanya ingin membagikan temuan saya.
Laptop saya dapat menangani program yang menumbuhkan 25,000
utas dan semua utas tersebut menulis beberapa data dalam basis data MySql dengan interval reguler 2 detik.
Saya menjalankan program ini 10,000 threads
untuk 30 minutes continuously
kemudian sistem saya stabil dan saya dapat melakukan operasi normal lainnya seperti browsing, membuka, menutup program lain, dll.
Dengan 25,000 threads
sistem slows down
tetapi tetap responsif.
Dengan 50,000 threads
sistem secara stopped responding
instan 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.
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.
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.
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.
Runnable
/ Callable
benar-benar perlu untuk terus berjalan, seperti ketika harus menangani komunikasi. Tapi itu sempurna untuk query SQL.
Setidaknya pada Mac OS X 10.6 32bit, ada batas (2560) oleh sistem operasi. Periksa untaian stackoverflow ini .
Jumlah utas maksimum tergantung pada hal-hal berikut:
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
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();
}
}
}
main
akan melempar OutOfMemoryError
pada 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.