2013-04-21 76 views
17

這個測試表明,可以在Java當我增加最大堆大小時,爲什麼最大線程數會減少?

System.out.println("Max memory " + Runtime.getRuntime().maxMemory()/1024/1024 + "M"); 
    for (int i = 0;; i++) { 
     Thread t = new Thread() { 
      public void run() { 
       try { 
        Thread.sleep(10000); 
       } catch (InterruptedException e) { 
       } 
      }; 
     }; 
     try { 
      t.start(); 
     } catch (Error e) { 
      System.out.println("Max threads " + i); 
      e.printStackTrace(); 
      System.exit(1); 
     } 
    } 

當我默認堆大小(256M)我得到

Max memory 247M 
Max threads 2247 
java.lang.OutOfMemoryError: unable to create new native thread 
    at java.lang.Thread.start0(Native Method) 
    at java.lang.Thread.start(Thread.java:691) 
    at test.Test1.main(Test1.java:19) 

當我增加最大堆大小來運行它創建線程的最大數量512M我得到

Max memory 494M 
Max threads 1906 
... 

當我增加最大堆大小1024M,我得到

Max memory 989M 
Max threads 1162 
... 

也就是說,堆內存越少線程越少。這是爲什麼?

+0

我們可以看看你的'java -version'嗎? – NPE 2013-04-21 08:10:36

+0

它是Windows 7上的HotSpot(TM)客戶端VM 1.7.0_21 – 2013-04-21 08:16:52

+0

更多線程=更少堆 – 2017-08-28 23:02:29

回答

18

每個線程都需要一個堆棧。分配給堆的內存越多,堆棧的內存就越少。

如果你使用的是32位JVM,這將會特別嚴重,因爲對於的所有內容(代碼,堆,堆棧等),進程將不會超過4GB的地址空間。我無法在我的64位盒子上重現這種行爲,無論我分配給堆的內存多少,「最大線程數」都保持不變。

值得注意的是,許多操作系統使您能夠調整堆棧的大小。在Unix上,這是使用ulimit -s完成的。

+0

您是否有任何消息來源?還有可能指定堆棧大小(全部或每個線程)? – 2013-04-21 10:57:29

0

我在猜測,增加堆大小(並使用它)會降低OS可用於創建新線程的內存量,因此無法創建像以前一樣多的線程。