簡體   English   中英

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顯示的不同方式執行操作。

https://bugzilla.redhat.com/show_bug.cgi?id=823030

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM