Baru -baru ini, jika Anda ingin menguji jumlah maksimum konkurensi di bawah OpenFire, Anda perlu membuka sejumlah besar utas untuk mensimulasikan klien. Saya selalu bingung tentang berapa banyak utas yang dapat dibuka oleh instance JVM, jadi saya berencana untuk mengujinya dan menemukan faktor -faktor berikut yang mempengaruhi jumlah utas:
-Xms | Ukuran tumpukan java intial |
-Xmx | Ukuran tumpukan java maksimum |
-Xss | Ukuran tumpukan untuk setiap utas |
Keterbatasan Sistem | Jumlah maksimum utas yang dapat dibuka di sistem |
Program pengujian adalah sebagai berikut: Kode Java:
impor java.util.concurrent.atomic.atomicinteger; TestThread kelas publik memperluas thread {private static final atomicinteger count = atomicinteger baru (); public static void main (string [] args) {while (true) (testThread baru ()). start (); } @Override public void run () {System.out.println (count.incrementandget ()); while (true) coba {thread.sleep (integer.max_value); } catch (InterruptedException e) {break; }}} Lingkungan Uji: Sistem: Ubuntu 10.04 Kernel Linux 2.6 (32-bit)
Memori: 2g
JDK: 1.7
Hasil tes:
Ø Tidak ada batasan sistem yang dipertimbangkan
-Xms | -Xmx | -Xss | hasil |
1024m | 1024m | 1024k | 1737 |
1024m | 1024m | 64k | 26077 |
512m | 512m | 64k | 31842 |
256m | 256m | 64k | 31842 |
Ketika jumlah utas yang dibuat mencapai 31.842, tidak ada utas yang dapat dibuat dalam sistem.
Dari hasil tes di atas, dapat dilihat bahwa meningkatkan heap memori (-xms, -xmx) akan mengurangi jumlah utas yang dapat dibuat, dan meningkatkan memori tumpukan benang (-XSS, nilai minimum parameter ini dalam sistem 32-bit adalah 60k) juga akan mengurangi jumlah utas yang dapat dibuat.
Ø Dikombinasikan dengan keterbatasan sistem
Batas jumlah utas 31842 ditentukan oleh jumlah maksimum utas yang dapat dihasilkan oleh sistem:/proc/sys/kernel/threads-max, tetapi nilai defaultnya adalah 32080. Ubah nilainya menjadi 1000: ECHO 10000>/proc/Sys/Kernel/Threads-Max, dan hasil uji yang dimodifikasi: sebagai berikut sebagai berikut sebagai berikut: sebagai berikut sebagai berikut: sebagai berikut: sebagai berikut sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut: sebagai berikut:
-Xms | -Xmx | -Xss | hasil |
256m | 256m | 64k | 9761 |
Dalam hal ini, apakah itu berarti bahwa sebanyak mungkin utas dapat dikonfigurasi? Buat modifikasi lain: ECHO 1000000>/proc/sys/kernel/threads-max, hasil tes yang dimodifikasi adalah sebagai berikut:
-Xms | -Xmx | -Xss | hasil |
256m | 256m | 64k | 32279 |
128m | 128m | 64k | 32279 |
Ditemukan bahwa jumlah utas tidak akan lagi meningkat setelah mencapai 32279. Setelah memeriksa, jumlah maksimum PID yang dapat dibuat oleh sistem Linux 32-bit adalah 32678. Nilai ini dapat dimodifikasi melalui/sistem/sistem kernel/pid_max yang lebih kecil. Ketika utas-max pasti, hasil tes untuk memodifikasi pid_max adalah sebagai berikut:
pid_max | -Xms | -Xmx | -Xss | hasil |
1000 | 128m | 128m | 64k | 582 |
10000 | 128m | 128m | 64k | 9507 |
Situasi pada Windows harus serupa, tetapi jumlah utas yang dapat dibuat pada Windows mungkin lebih kecil dari Linux. Server berdasarkan model utas selalu dibatasi oleh jumlah utas.
Jumlah maksimum yang dapat dihasilkan dalam JVM dipengaruhi oleh ukuran memori heap JVM, ukuran memori tumpukan utas, dan jumlah maksimum utas yang dapat dibuat oleh sistem (implementasi benang Java didasarkan pada mekanisme threading di bawah sistem yang mendasarinya, _beginthreadex di bawah windows, dan pthread_create). Jumlah spesifik dapat diperkirakan berdasarkan memori maksimum yang dapat diakses oleh proses Java (umumnya 2G pada sistem 32-bit), memori tumpukan, dan memori tumpukan utas.
urutan:
Diuji pada sistem Linux 64-bit (Centos6, memori 3G), saya menemukan bahwa ada parameter lain yang membatasi jumlah utas: MaxuserProcess (dapat dilihat melalui Ulimita, nilai defaultnya adalah 1024, dan nilai ini dapat dimodifikasi melalui Ulimitu). Nilai ini tidak terbatas di lingkungan uji Ubuntu 32-bit di atas.
Ubah Threads -Max, PID_MAX, MaxuserProcess, ketiga parameter menjadi 100000, -xms, -xmx sekecil mungkin (128m, 64m), dan -xss sekecil mungkin (104k pada 64 bit, nilainya bisa 128k). Diprediksi sebelumnya dalam lingkungan pengujian ini, jumlah utas hanya akan terbatas pada ukuran memori (3G) dari lingkungan pengujian. Namun, hasil tes aktual adalah bahwa ketika jumlah utas mencapai 32k (32768, jumlah maksimum yang dibuat adalah sekitar 33.000), JVM melempar peringatan: upaya semua orang yang gagal gagal, dan kemudian outofemoryerror tidak dapat membuat utas lokal. Setelah memeriksa memori, saya menemukan bahwa masih ada banyak waktu luang, jadi seharusnya tidak karena kapasitas memori. Peringatan Google tidak membuahkan hasil. Saya tidak tahu mengapa, dan perlu penelitian lebih lanjut.
Langkah 2:
Saya tidak sengaja menemukan artikel [7] hari ini dan segera mencobanya. Tentu saja, faktor ini akan mempengaruhi jumlah kreasi utas. Menurut deskripsi dalam artikel, jumlah/proc/sys/vm/max_map_count digandakan, dari 65536 hingga 131072. Jumlah total utas yang dibuat telah mencapai 65.000+. Komputer pada dasarnya harus macet (memori 3G) ... Saya secara singkat memeriksa fungsi parameter ini, dan deskripsi dalam [8] adalah sebagai berikut:
“File ini berisi jumlah maksimum memoriMapAreAsprocessMayhave.MemoryMapareaseuseAside-Efek CallingMalloc, langsung bymapandmprotect, andalso saat memuat perpustakaan bersama.
Sementara sebagian besar aplikasi dibutuhkan kurang dari peta, program tertentu, terutama mallocdebuggers, dapat mengkonsumsi pantat, misalnya, upooneortwomapsperlocation.
ThedefaultValueis65536. "
Oke, masalah ini akhirnya diselesaikan sepenuhnya. Akhirnya, faktor -faktor yang mempengaruhi jumlah utas Java dirangkum:
Mesin virtual java itu sendiri: -xms, -xmx, -xss;
Keterbatasan Sistem:
/proc/sys/kernel/pid_max,
/proc/sys/kernel/thread-max,
max_user_process (ULIMIT-U),
/proc/sys/vm/max_map_count.
Meringkaskan
Di atas adalah semua tentang tes sederhana JVM yang mendukung jumlah utas maksimum. Saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya.