Java VM'sini kaç iş parçacığı destekleyebilir? Bu satıcıya göre değişir mi? işletim sistemine göre? diğer faktörler?
Java VM'sini kaç iş parçacığı destekleyebilir? Bu satıcıya göre değişir mi? işletim sistemine göre? diğer faktörler?
Yanıtlar:
Bu, kullandığınız CPU'ya, işletim sistemine, diğer işlemlerin ne yaptığına, hangi Java sürümünü kullandığınıza ve diğer faktörlere bağlıdır. Bir Windows sunucusunun makineyi indirmeden önce> 6500 İş Parçacığı olduğunu gördüm. Konuların çoğu elbette hiçbir şey yapmıyordu. Makine yaklaşık 6500 İş Parçasına (Java'da) çarptığında, tüm makine sorun yaşamaya ve kararsız hale geldi.
Deneyimlerim, Java'nın (son sürümler), bilgisayarın kendisi sorunsuz olarak barındırabileceği kadar çok Threads tüketebileceğini gösteriyor.
Tabii ki, yeterli RAM'e sahip olmalısınız ve Java'nın, Threads'ın yaptığı her şeyi yapmak ve her bir Thread için bir yığına sahip olmak için yeterli belleğe sahip olması gerekir. Modern CPU'lu (en son birkaç nesil AMD veya Intel) ve 1-2 Gig bellek (işletim sistemine bağlı olarak) olan herhangi bir makine binlerce Threads ile bir JVM'yi kolayca destekleyebilir .
Bundan daha spesifik bir cevaba ihtiyacınız varsa, en iyi bahsiniz profil yapmaktır.
Hım, çok.
Burada birkaç parametre var. Spesifik VM ve ayrıca VM üzerinde genellikle çalışma zamanı parametreleri de vardır. Bu biraz işletim sistemi tarafından yönlendirilir: altta yatan işletim sisteminin iş parçacıkları için hangi desteği vardır ve bunlara ne gibi sınırlamalar getirir? VM aslında işletim sistemi düzeyinde iş parçacıkları kullanıyorsa, eski kırmızı iş parçacığı / yeşil iş parçacığı.
"Destek" ne demek başka bir soru. Bir Java programı yazarsanız,
class DieLikeADog {
public static void main(String[] argv){
for(;;){
new Thread(new SomeRunaable).start();
}
}
}
(ve küçük sözdizimi detaylarından şikayet etmeyin, ilk kahvemdeyim) o zaman kesinlikle yüzlerce veya binlerce iş parçacığının çalışmasını beklemelisiniz. Ancak bir iş parçacığı oluşturmak nispeten pahalıdır ve zamanlayıcı yükü yoğunlaşabilir; bu iş parçacıklarının yararlı bir şey yapabileceği açık değil.
Tamam, dayanamadım. İşte benim birkaç test programım, birkaç süslemeyle:
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();
}
}
}
Intel ve Java 6 5 üzerinde OS / X 10.5.6'da (yorumlara bakın), işte aldığım şey
Yeni konu # 2547 Yeni konu # 2548 Yeni konu # 2549 Konu oluşturulamıyor: 5 Yeni konu # 2550 "Main" iş parçacığında kural dışı durum java.lang.OutOfMemoryError: yeni yerel iş parçacığı oluşturulamıyor java.lang.Thread.start0 (Yerel Yöntem) java.lang.Thread.start adresinde (Thread.java:592) DieLikeADog.main adresinde (DieLikeADog.java:6)
Charlie Martin'in gönderisini okuduktan sonra, yığın boyutunun oluşturabileceğiniz iş parçacığı sayısında herhangi bir fark yaratıp yaratmadığını merak ettim ve sonuçtan tamamen şaşkına döndüm.
Vista Home Premium SP1'de JDK 1.6.0_11 kullanarak, Charlie'nin 2 MB ile 1024 MB arasında farklı yığın boyutlarına sahip test uygulamasını yürüttüm.
Örneğin, 2 MB yığın oluşturmak için, JVM'yi -Xms2m -Xmx2m değişkenleriyle çağırırdım.
İşte sonuçlarım:
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
Yani, evet, yığın boyutu kesinlikle önemlidir. Ancak yığın boyutu ve maksimum iplik sayısı arasındaki ilişki, ters orantılıdır.
Hangisi garip.
Bu sorunun oldukça eski olduğunu biliyorum ama sadece bulgularımı paylaşmak istiyorum.
Dizüstü bilgisayarım iş 25,000
parçacıkları üreten programı ve tüm bu iş parçacıkları MySql veritabanında 2 saniye düzenli aralıklarla bazı veri yazmak mümkün .
Bu programı çalıştırdım 10,000 threads
, 30 minutes continuously
o zaman da sistemim kararlıydı ve göz atma, açma, diğer programları kapatma vb.Gibi diğer normal işlemleri yapabildim.
İle 25,000 threads
sisteme slows down
ancak duyarlı kalır.
İle 50,000 threads
sisteme stopped responding
anında ve elle sistemimi yeniden gerekiyordu.
Sistem bilgilerim aşağıdaki gibidir:
Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6
Çalıştırmadan önce jvm argümanını ayarladım -Xmx2048m
.
Umarım yardımcı olur.
Mutlak teorik maksimum genellikle sürecin bir iş parçacığı yığın boyutu bölü kullanıcı adres alanı (tüm bellek iplik yığınlar için ayrılmıştır eğer gerçekte, sen ... bir çalışma programı olmaz gerçi).
Örneğin, her bir iş parçacığına 128K yığın boyutu veren her işlemin 2GB kullanıcı adres alanına sahip olduğu 32 bit Windows altında, mutlak maksimum 16384 iş parçacığı (= 2 * 1024 * 1024/128) beklersiniz. Uygulamada, XP altında yaklaşık 13.000 kişi başlatabileceğimi fark ettim.
O zaman, aslında (a) Eğer birçok kodunuzda ipler değil (örneğin ardından ... notifyAll () çağırarak aynı nesne üzerinde hepsini bekleme yapma gibi) açıkça saçma şeyler yapmak hokkabazlık yönetebilir, ve (b) işletim sisteminin yapıp yapamayacağı. Prensip olarak, (a) 'nın yanıtı da "evet" ise (b)' nin yanıtı "evet" tir.
Bu arada, iş parçacığının yapıcısında yığın boyutunu belirtebilirsiniz ; bunun için VM parametreleriyle uğraşmanıza gerek yoktur (ve muhtemelen olmamalıdır).
Binlerce çekirdekli (9000?) Bir ticaret fuarında uygulamalarından birini bazı özel makinelerde çalıştırdığı bir Clojure konuşması duyduğumu hatırlıyorum ve hepsini yükledi. Ne yazık ki, şu anda bağlantıyı bulamıyorum (yardım?).
Buna dayanarak, donanım ve kodunuzun JVM değil, sınırlayıcı faktörler olduğunu söylemek güvenli olduğunu düşünüyorum.
Charlie'nin DieLikeACode sınıfıyla oynadıktan sonra, Java iş parçacığı yığın boyutu kaç tane iş parçacığı oluşturabileceğinizin büyük bir parçası gibi görünüyor.
-Xss set java iplik yığını boyutu
Örneğin
java -Xss100k DieLikeADog
Ancak, Java'nın Yürütücü arabirimi vardır. Bunu kullanacağım, binlerce Runnable görevi gönderebileceksin ve İcracı'nın bu görevleri sabit sayıda iş parçacığıyla işlemesini sağlayabileceksin.
Runnable
/ Callable
aslında iletişimin üstesinden gelmesi gerektiği gibi sürekli olarak çalışması gerekiyorsa çalışmaz. Ancak SQL sorguları için mükemmeldir.
En azından Mac OS X 10.6 32bit'te, işletim sistemi tarafından bir sınır (2560) vardır. Bu yığın akışı ipliğini kontrol edin .
Maksimum iş parçacığı sayısı aşağıdakilere bağlıdır:
Modern (systemd) linux sistemleri için ek bilgiler.
Bu konuda ince ayar gerektirebilecek birçok kaynak vardır (örneğin, maksimum JVM iş parçacığı sayısı nasıl artırılır (Linux 64bit) ); ancak sistemd'de pids.max değerini ayarlayan sistemd "TasksMax" sınırı ile yeni bir sınır getirilir.
Oturum açma oturumları için UserTasksMax varsayılan değeri pids_max (genellikle 12,288) çekirdek sınırının% 33'üdür ve /etc/systemd/logind.conf dosyasında geçersiz kılınabilir.
Hizmetler için, DefaultTasksMax varsayılan değeri pids_max çekirdek sınırının% 15'idir (genellikle 4.915). Hizmet için "systemctl edit" de TasksMax ayarını geçersiz kılabilir veya /etc/systemd/system.conf içinde DefaultTasksMax öğesini güncelleyebilirsiniz
İstediğiniz sayıda iş parçacığını işleyebilirsiniz; sınır yok. Bir filmi izlerken ve NetBeans kullanırken aşağıdaki kodu çalıştırdım ve düzgün / makineyi durdurmadan çalıştı. Bence bu programdan daha fazla iş parçacığı tutabilirsiniz.
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
makineme bir atar OutOfMemoryError
. Belki @AnilPal, bunu farketmedin. main(..)
Hatayı attıktan sonra yeni iş parçacıkları oluşturmanın ne zaman durduğunu açıkça görmek için yönteme başka bir print ifadesi eklemenizi öneririm .