Red Hat Linux における Java シングル プロセス スレッドの制限が低い

StackOverflow https://stackoverflow.com/questions/116640

  •  02-07-2019
  •  | 
  •  

質問

Java 1.6 (1.6.0_02 または 1.6.0_04) を使用して Red Hat Linux (カーネル バージョンは 2.4.21-37.ELsmp) を実行しているテスト マシンで問題が発生しています。問題は、単一スレッド グループ内に一定数のスレッドが作成されると、オペレーティング システムがそれ以上作成しようとしない、または作成できなくなることです。

C のスレッド制限プログラムでは約 1.5k のスレッドを作成できたため、これは Java のスレッド作成に特有のものと思われます。さらに、これは Java 1.4 JVM では起こりません...1.4k を超えるスレッドを作成できますが、それらは OS に関して明らかに異なる方法で処理されます。

この場合、切断されるスレッドの数はわずか 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 設定がこの問題を引き起こしているかについてのアイデアがあれば幸いです。

編集:で言及されたスレッド制限プログラムを実行する 台座, 、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 モデルを使用していることが判明しました。

役に立ちましたか?

解決 2

NPTL スレッドを使用してカーネルを新しいバージョン (2.6.something) に更新すると、この問題が修正されました。

他のヒント

見ましたか このリソース?thread-limit を実行してスレッドの最大数を見つけることができ、glibc をコンパイルすることで調整できると記載されています。

これは 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帰属
所属していません StackOverflow
scroll top