2012-11-28 65 views
1

我需要一些關於如何最好地調整我的內存設置以允許更多線程的輸入。爲什麼-Xss不增加創建的線程數量?

我通過How many threads can a Java VM support?上的構成閱讀並遵循java中的例子(dieLikeaDog),它確實有效,它在死亡之前產生了800個線程。

如在(例如dieLikeaDog)以上的鏈接,該代碼使得它可以在所有線程,直到下面的錯誤的結果:java.lang.OutOfMemoryError:無法在命令創建新的本地線程

指定XSS行(例如java -Xss104k dieLikeADog)不會更改創建的線程數。

我也嘗試更改-Xms和-Xmx,並且都沒有改變它可能產生的線程數量。

改變線程數的一件事是我-u ulimit(用於最大用戶進程)。做得更大,確實增加了線程的數量。

我ulimits如下:

$ ulimit -a 
core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 0 
file size    (blocks, -f) unlimited 
pending signals     (-i) 46588 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 1024 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

我,因爲我從閱讀其他例子是指定較小-Xss應該增加線程數認爲有點糊塗。

是否還有其他事情正在阻止Xss的工作?

如果它很重要,我是一個64位的Fedora 15系統上運行(與RAM的6場音樂會):

OS: 
    Linux 
    2.6.42.12-1.fc15.x86_64 
    amd64 

    JVM: 
    Sun Microsystems Inc. 
    Java(TM) SE Runtime Environment 
    Java HotSpot(TM) 64-Bit Server VM 
    1.6.0_27 
+0

死亡的原因是什麼?也許只是沒有足夠的記憶?嘗試增加-Xmx –

+1

好問題。正如我上面所說的,我嘗試更改-Xms和-Xmx,並且不改變它可能產生的線程數量。在上面的(dieLikeaDog示例)鏈接中,代碼創建了所有可能的線程,直到出現以下錯誤:java.lang.OutOfMemoryError:無法創建新的本機線程 –

+0

看起來像是某種東西(不是線程)誰吃了所有的內存。爲了確保,嘗試-Xms可以減少線程的堆棧內存。嘗試使用內存分析工具找出生豬。 –

回答

1

-Xss參數控制粘糊內存是如何分配給每個線程的堆棧。選擇一個值是平衡堆棧深度和可用內存的一個例子。設置-Xss104k的值意味着您的可用內存爲012KB(設置爲-Xmx)將爲每個啓動的線程的堆棧消耗。 如果從-Xmx1024k開始,那麼在您達到10個線程之前內存將會耗盡,因爲1M的內存包含堆和類(permgen)以及線程堆棧。

我的方法是首先檢查要在線程中運行的代碼。遞歸繁重的代碼需要更多的堆棧。只是迭代大量數據的代碼可能需要很少的堆棧。

平衡所涉及的力量的經驗方法是減少-Xss,直到您得到StackOverflowError。這意味着你的線程正在耗盡堆棧。添加一些填充到工作的最後一個值。如果最後一個沒有導致StackOverflowError的值是'-Xss1k , the try -Xss2k or -Xss3k . If the stack is wiping out at something like 10k I'd try just bumping to 15k`。

現在你有一個線程堆棧的大小。你的總內存(-Xmx)減去permgen,減去所需的堆量就可以得到剩下的線程數。如果你需要1000K的堆和50K的permgen,並且你計算出2K的堆棧大小,那麼運行10個線程,你會看到-Xmx1070K作爲你的最小內存。

這就是說,看看你想要完成什麼。爲什麼你需要更多的線程?也許答案不是更多線程,而是一種不同的算法,可以在使用較少線程的同時更快地處理數據。

更新

我擊中了,我發現是不正確的我原來的答覆的部分。

堆棧空間不是從堆空間取出的,它們是分開分配的。 線程堆棧和堆都計入進程的虛擬內存。減少堆允許更多線程並增加它允許更少。

在32位JVM上,我能夠將堆棧大小減少到1K。 在64位JVM上,最低爲104K。

我在使用4G內存和2個內核的64位Windows 7機器上進行了一些測試。

使用32位JVM,-Xss8k-Xmx128m該程序給我〜5000個線程。這似乎是最好的情況。我沒有找到可以增加超出這一點的線程數量的選項組合。如果我增加了堆的大小,最大的線程就會消失。線程堆棧大小似乎可能與系統頁面大小有關,因爲如果我選擇小於8k的堆棧,最大線程實際上會變得更糟。

對於Ubuntu Quantal上的32位JVM,〜5000線程限制似乎也適用。

對於64位JVM,這是一個完全不同的故事。用-Xss104k-Xmx128m該程序超過了50000個線程。那時Windows得到了真的不高興。它停止響應幾分鐘,然後開始殺死其他進程。我在試圖釋放更多的記憶。

更新:

更多關於Ubuntu的測試:我發現我有虛擬內存的ulimit集。在ulimit -v unlimited之後該程序最高可達〜36000個線程。

+0

我們不能輕易使用較少的線程,因爲在我們的程序中有很多不同的應用程序使用駱駝和jms(爲聽衆等創建線程)。 –

+0

重新使用較小的Xss大小,我應該能夠使用小尺寸如64k?如果我嘗試java -Xss64k dieLikeADog,則得到: 指定的堆棧大小太小,請指定至少104k 無法創建Java虛擬機。 –

+0

我很高興聽到您確認104是低限,因爲這是我發現的。我感到困惑的是,爲什麼運行以下4個命令都作出相同的線程數,我(749): 的Java dieLikeADog 的Java -Xss104k dieLikeADog 的java -Xmx128m dieLikeADog 的Java -Xss104k -Xmx128m dieLikeADog –

0

其原因可能在於你給了ulimits內:

max user processes    (-u) 1024 

每個線程將計入此值。因爲你不僅運行JVM,相當多的線程已經從該值中扣除。

嘗試執行

ulimit -u 4000 

,並重新運行測試(已執行的命令外殼之內!),你可以創建的線程數量不應該增加。

相關問題