- 默認(rèn)情況下,一個線程的棧要預(yù)留1M的內(nèi)存空間
而一個進程中可用的內(nèi)存空間只有2G,所以理論上一個進程中最多可以開2048個線程 - 但是內(nèi)存當(dāng)然不可能完全拿來作線程的棧,所以實際數(shù)目要比這個值要小。你也可以通過連接時修改默認(rèn)棧大小,將其改的比較小,這樣就可以多開一些線程。如將默認(rèn)棧的大小改成512K,這樣理論上最多就可以開4096個線程。即使物理內(nèi)存再大,一個進程中可以起的線程總要受到2GB這個內(nèi)存空間的限制。
- 比方說你的機器裝了64GB物理內(nèi)存,但每個進程的內(nèi)存空間還是4GB,其中用戶態(tài)可用的還是2GB。
- 內(nèi)核態(tài). CPU可以訪問內(nèi)存所有數(shù)據(jù), 包括外圍設(shè)備, 例如硬盤, 網(wǎng)卡. CPU也可以將自己從一個程序切換到另一個程序
- 用戶態(tài):.只能受限的訪問內(nèi)存, 且不允許訪問外圍設(shè)備. 占用CPU的能力被剝奪, CPU資源可以被其他程序獲取
- 如果是同一臺機器內(nèi)的話,能起多少線程也是受內(nèi)存限制的。每個線程對象都要站用非頁面內(nèi)存,而非頁面內(nèi)存也是有限的,當(dāng)非頁面內(nèi)存被耗盡時,也就無法創(chuàng)建線程了。
- 如果物理內(nèi)存非常大,同一臺機器內(nèi)可以跑的線程數(shù)目的限制值會越來越大。在Windows下寫個程序,一個進程Fork出2000個左右線程就會異常退出了,為什么?這個問題的產(chǎn)生是因為windows32位系統(tǒng),一個進程所能使用的最大虛擬內(nèi)存為2G,而一個線程的默認(rèn)線程棧StackSize為1024K(1M),這樣當(dāng)線程數(shù)量逼近2000時,2000*1024K=2G(大約),內(nèi)存資源就相當(dāng)于耗盡
影響最大線程大小的因素
- Java虛擬機本身
- Xms 初始堆大小
- Xmx 最大堆大小
- Xss 每個線程的堆棧大小
- 系統(tǒng)限制
- /proc/sys/kernel/pid_max
- /proc/sys/kernel/thread-max
- max_user_process(ulimit -u)
- /proc/sys/vm/max_map_count
其他突破線程問題
- 多進程-啟動多線程
- 使用異步請求
- 無論是使用多進程-多線程,還是異步請求,最主要的影響還是電腦本身的配置
下面是具體配置
Windows
httpd.exe -l 會看見 mpm_winnt.c windows默認(rèn)執(zhí)行 mpm_winnt_module方式 (暫未找到修改成其他方式的方法)
1.httpd.conf 文件去掉 Include conf/extra/httpd-mpm.conf 前面的#
2.修改extra/httpd-mpm.conf 最下面 或 查找 mpm_winnt_module 修改ThreadsPerChild 和 MaxRequestsPerChild
#每個子進程建立的線程數(shù)
ThreadsPerChild 1 默認(rèn)150
#指令設(shè)置每個子進程在其生存期內(nèi)允許伺服的最大請求數(shù)量。
#到達MaxRequestsPerChild的限制后,子進程將會結(jié)束。
#如果MaxRequestsPerChild為"0",子進程將永遠(yuǎn)不會結(jié)束。
MaxRequestsPerChild 10 默認(rèn)0
根據(jù)自己網(wǎng)站并發(fā)數(shù)量設(shè)置:
ThreadsPerChild 設(shè)置 網(wǎng)站平均在線人數(shù)
MaxRequestsPerChild 設(shè)置最高在線人數(shù)的值
Linux
ps -ef | grep httpd | wc -l 查看當(dāng)前 httpd進程數(shù)
apachectl -l 會看見 prefork.c Linux默認(rèn)執(zhí)行 mpm_prefork_module
- httpd.conf 文件去掉 Include conf/extra/httpd-mpm.conf 前面的#
2.修改extra/httpd-mpm.conf 最上面 或 查找 mpm_prefork_module
StartServers 5 #默認(rèn)啟動線程數(shù)
#指令設(shè)置空閑子進程的最小數(shù)量。
#所謂空閑子進程是指沒有正在處理請求的子進程。
#如果當(dāng)前空閑子進程數(shù)少于MinSpareServers ,
#那么Apache將以最大每秒一個的速度產(chǎn)生新的子進程。
#只有在非常繁忙機器上才需要調(diào)整這個參數(shù)。將此參數(shù)設(shè)的太大通常是一個壞主意。
MinSpareServers 5 #
#指令設(shè)置空閑子進程的最大數(shù)量。
#所謂空閑子進程是指沒有正在處理請求的子進程。
#如果當(dāng)前有超過MaxSpareServers數(shù)量的空閑子進程,
#那么父進程將殺死多余的子進程。
#只有在非常繁忙機器上才需要調(diào)整這個參數(shù)。
#將此參數(shù)設(shè)的太大通常是一個壞主意。
#如果你將該指令的值設(shè)置為比MinSpareServers小,
#Apache將會自動將其修改成"MinSpareServers+1"。
MaxSpareServers 10 #
MaxClients 150 #apache可以同時處理的請求
MaxRequestsPerChild 0 #如windows MaxRequestsPerChild