作者:miracle1919
http://www.importnew.com/10780.html
McGovernTheory在StackOverflow提了這樣一個問題:Java虛擬機最多支持多少個執行緒?跟虛擬機開發商有關么?跟作業系統呢?還有其他的因素嗎?
Eddie的回答:
這取決于你使用的CPU,作業系統,其他行程正在做的事情,你使用的Java的版本,還有其他的因素,我曾經見過一臺Windows服務器在宕機之前有超過6500個執行緒,當然,大多數執行緒什么事情也沒有做,一旦一臺機器上有差不多6500個執行緒(Java里面),機器就會開始出問題,并變得不穩定,
以我的經驗來看,JVM容納的執行緒與計算機本身性能是正相關的,
當然了,你要有足夠的本機記憶體,并且給Java分配了足夠的記憶體,讓每個執行緒都可以擁有堆疊(虛擬機堆疊),可以做任何想做的事情,任何一臺擁有現代CPU(AMD或者是Intel最近的幾代)和1-2G記憶體(取決于作業系統)的機器很容易就可以支持有上千個執行緒的Java虛擬機,
如果你需要一個更精確的答案,最好是自己做壓測,
Charlie Martin的回答:
這里有很多的引數(可以設定),對于特定的虛擬機,都會有自己的運行時引數,(最大執行緒數)一定程度上由作業系統決定的:底層的作業系統要給執行緒提供哪些支持?施加哪些限制?虛擬機使用的是原生的作業系統的執行緒還是red thread或者green thread?
作業系統提供的支持是另一個問題,如果你向下面這樣寫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();
}
}
}
在Intel的OS/X 10.5.6系統上,Java 5的輸出如下:
New thread #2547
New thread #2548
New thread #2549
Can't create thread: 5
New thread #2550
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:592)
at DieLikeADog.main(DieLikeADog.java:6)
benjismith的回答:
讀了Charlie Martin的回復以后,我很想知道堆記憶體的大小是否能夠給創建的執行緒數帶來不同,然后我就被結果驚呆了:在Vista Home Premium SP1系統上,使用JDK 1.6.0_11,設定堆記憶體的大小從2M到1024M來執行Charlie的測驗程式,比如:創建2M的堆記憶體,我使用的虛擬機引數是:-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
所以,堆的大小確實很重要,但是,堆大小和最大執行緒數卻是呈反比例關系,
這太詭異了!
Neil Coffey的回答:
絕對理論上的最大執行緒數是行程的用戶地址空間除以執行緒堆疊的大小(現實中,如果記憶體全部給執行緒堆疊使用,就不會有能運行的程式了),因此,以32位Windows系統為例,每一個行程的用戶地址空間是2G,假如每個執行緒堆疊的大小是128K,最多會有16384(=2*1024*1024 / 128)個執行緒,實際在XP系統上,我發現大約能啟動13000個執行緒,
然后,我認為,你的問題本質上是:(a)你是否可以在你的代碼中有效的管理許多的執行緒,不讓他們做很顯然是愚蠢的事情(比如:讓他們在同一個object物件上等待隨后被呼叫notifyAll()…),(b)作業系統是否可以有效地管理這許多執行緒,基本上來說,如果(a)的答案是”yes”的話,(b)的答案也是”yes”,
很巧的是,你可以在Thread的建構式中設定執行緒堆疊的大小,但是,你不需要也不應該把這個和虛擬機引數弄混淆,
關注公眾號Java技術堆疊回復"面試"獲取我整理的2020最全面試題及答案,
推薦去我的博客閱讀更多:
1.Java JVM、集合、多執行緒、新特性系列教程
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
4.Java、后端、架構、阿里巴巴等大廠最新面試題
覺得不錯,別忘了點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/157909.html
標籤:Java
下一篇:Spring系列.SpEL運算式
