for Red Hat Linux中低Java單進程線程限制




linux install jre (4)

用NPTL線程更新內核到一個更新的版本(2.6.something)解決了這個問題。

我在使用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設置似乎也沒有改變任何東西(這是可以預料的,考慮到這個問題似乎與本地操作系統線程創建)。

“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

用戶進程限制似乎不是問題。 搜索有關錯誤信息的信息並沒有太多,但是這篇文章似乎表明,至少有一些紅帽內核將進程限制為分配給堆棧的300 MB內存,並且每個線程堆棧的內存為10 MB像這個問題可能在那裡(雖然這似乎很奇怪,也不太可能)。

我已經嘗試用“ulimit -s”來改變堆棧大小來測試這個,但是除了10240和JVM以外的任何值都不會以下面的錯誤開始:

Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.

我通常可以繞過Linux,但是我對系統配置並不了解,而且我也沒有找到任何具體的解決這種情況的方法。 任何想法什麼系統或JVM設置可能會造成這一點,將不勝感激。

編輯 :運行底座提到的線程限製程序,直到試圖創建第1529個線程才有失敗。

使用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模型。



Answer #2

你看過這個資源嗎? 它指出,你應該能夠運行線程限制來找到最大線程數,並可以通過編譯glibc來調整它。


Answer #3

你可以用JRockit JVM試試嗎? IIRC,它與Sun JVM的庫存有不同的線程模型。





redhat