JVM 可開闢線程數量受什麼影響

首先要說明一點,Java線程的實現是基於底層系統的線程機制來實現的,程序中開的線程並不所有取決於JVM虛擬機棧,而是取決於CPU,操做系統,其餘進程,Java的版本。JVM的線程與計算機自己性能相關。centos

之前寫過一個例子,統計能夠開闢的線程數量,經過不斷的申請Thread,最終會報錯,輸出一個當前開闢線程的數量:性能

public class ThreadCount{
    private static Object obj = new Object();
    private static int count = 0;
    public static void main(String[] args){
        for(;;){
            new Thread(new Runnable(){
                    public void run(){
                        synchronized(obj){
                            count += 1;
                            System.out.println("Thread #"+count);
                        }
                        for(;;){
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e){
                                System.err.println(e);
                            }
                        }
                    }
                }).start();
        }
    }
}

運行結果上傳圖片有點問題,結果就不貼了,每一個人的機器,結果都是不一樣的,能夠運行下。測試

 

既然線程數量於計算機自己相關,咱們是否是不可調控,是固定的呢?操作系統

答案顯然不是的,在不考慮系統自己限制的狀況下,主要跟JVM一下幾點有關:線程

  • -Xms 初始堆大小 (在實際生產中,通常把-Xms和-Xmx設置成同樣的。)
  • -Xmx 最大堆大小
  • -Xss 每一個線程棧大小

結論1:當給JVM的堆內存分配的越大,系統可建立的線程數量就越少(能夠經過上面測試程序,不斷的改變-Xmx,-Xms的值,觀看最後異常時的線程數量)。這個如何理解呢?很簡單,由於線程佔用的是系統空間,因此當JVM的堆內存越大,系統自己的內存就越少,天然可生成的線程數量就越少。code

結論2:當-Xss的的值越小,可生成的線程數量就越多。(同樣能夠經過上面測試,保持-Xmx,-Xms不變,改變-Xss的值,jdk5如下默認好像是256K,以上默認爲1M,具體記不太清楚了)。這個理解也很簡單,線程可用空間保持不變,每一個線程佔用的棧內存大小變小,天然可生成的線程數量就越多。進程

 

那麼是否是不斷加大可用內存,線程數量也會不斷增加呢?圖片

這個固然不是,上面我特地加粗了不考慮系統本省限制的狀況,因此說線程數量還與系統限制有關。主要跟一下幾個參數有關(Linux下的):內存

  • /proc/sys/kernel/pid_max 增大,線程數量增大,pid_max有最高值,超過以後再也不改變,並且32,64位也不同
  • /proc/sys/kernel/thread-max 系統能夠生成最大線程數量
  • max_user_process(ulimit -u)centos系統上纔有,沒有具體研究
  • /proc/sys/vm/max_map_count 增大,數量增多

 

總結:線程最大數量由JVM的堆(-Xmx,-Xms)大小、Thread的棧(-Xss)內存大小、系統最大可建立的線程數的限制參數三個方面影響。不考慮系統限制,能夠經過這個公式估算:虛擬機

線程數量 = (機器自己可用內存 - JVM分配的堆內存) / Xss的值。

 

做者:Elliot 連接:https://www.zhihu.com/question/45563937/answer/99495011 來源:知乎 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索