[英]Unicode working on Windows but not Red Hat Linux : Java
[英]Low Java single process thread limit in Red Hat Linux
我在使用Java 1.6(1.6.0_02或1.6.0_04)運行Red Hat Linux(內核版本為2.4.21-37.ELsmp)的測試機器上遇到問題。 問題是,一旦在單個線程組中創建了一定數量的線程,操作系統就不願意或不能再創建了。
這似乎是特定於Java創建線程,因為C線程限制程序能夠創建大約1.5k線程。 此外,Java 1.4 JVM不會發生這種情況......它可以創建超過1.4k的線程,盡管它們顯然在操作系統方面的處理方式不同。
在這種情況下,它切斷的線程數僅為29個線程。 這可以通過一個簡單的Java程序來測試,該程序只是創建線程,直到它出現錯誤,然后打印它創建的線程數。 錯誤是
java.lang.OutOfMemoryError: unable to create new native thread
這似乎不受其他進程或用戶使用的線程數或系統當時使用的內存總量等因素的影響。 像Xms,Xmx和Xss這樣的JVM設置似乎也沒有改變任何東西(這是預期的,考慮到問題似乎與本機OS線程創建有關)。
“ulimit -a”的輸出如下:
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) 4 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 7168 virtual memory (kbytes, -v) unlimited
用戶進程限制似乎不是問題。 搜索可能出錯的信息並沒有太多,但這篇文章似乎表明至少有一些Red Hat內核將進程限制為為堆棧分配的300 MB內存,並且每個線程10 MB用於堆棧,似乎喜歡這個問題可能就在那里(雖然看起來很奇怪,也不太可能)。
我已經嘗試用“ulimit -s”更改堆棧大小來測試它,但除了10240和JVM之外的任何值都不會以錯誤:
Error occurred during initialization of VM Cannot create VM thread. Out of system resources.
我通常可以繞過Linux,但我真的不太了解系統配置,而且我無法找到任何具體解決這種情況的方法。 關於什么系統或JVM設置可能導致這一點的任何想法將不勝感激。
編輯 :運行由提到的線程限制程序的底座 ,也沒有失敗,直到它試圖創建第一千五百二十九線程。
使用1.4 JVM也沒有發生這個問題(確實發生在1.6.0_02和1.6.0_04 JVM上,目前無法使用1.5 JVM進行測試)。
我正在使用的線程測試的代碼如下:
public class ThreadTest {
public static void main(String[] pArgs) throws Exception {
try {
// keep spawning new threads forever
while (true) {
new TestThread().start();
}
}
// when out of memory error is reached, print out the number of
// successful threads spawned and exit
catch ( OutOfMemoryError e ) {
System.out.println(TestThread.CREATE_COUNT);
System.exit(-1);
}
}
static class TestThread extends Thread {
private static int CREATE_COUNT = 0;
public TestThread() {
CREATE_COUNT++;
}
// make the thread wait for eternity after being spawned
public void run() {
try {
sleep(Integer.MAX_VALUE);
}
// even if there is an interruption, dont do anything
catch (InterruptedException e) {
}
}
}
}
如果你使用1.4 JVM運行它,它將掛起,因為它無法創建任何更多線程並需要kill -9(至少它對我來說)。
更多編輯:
事實證明,遇到問題的系統是使用LinuxThreads線程模型,而另一個工作正常的系統是使用NPTL模型。
你看過這個資源了嗎? 它聲明你應該能夠運行線程限制來找到最大線程數,並可以通過編譯glibc來調整它。
使用NPTL線程將內核更新為更新版本(2.6.something)可以解決此問題。
這是用Ubuntu Linux(1GB RAM)
dsm@localhost:~$ javac ThreadTest.java
dsm@localhost:~$ java ThreadTest
8113
dsm@localhost:~$ java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
dsm@localhost:~$
你能用JRockit JVM試試嗎? IIRC,它具有與Sun JVM庫存不同的線程模型。
/etc/security/limits.d/90-nproc.conf
的設置可能會覆蓋/etc/security/limits.conf
設置。 這可能會導致系統以ulimit -u
顯示的不同方式執行操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.