Java VMはいくつのスレッドをサポートできますか?


212

Java VMはいくつのスレッドをサポートできますか?これはベンダーによって異なりますか?オペレーティングシステムで?他の要因?

回答:


170

これは、使用しているCPU、OS、他のプロセスが実行していること、使用しているJavaリリース、およびその他の要因によって異なります。マシンを停止する前に、Windowsサーバーのスレッド数が6500を超えることを確認しました。もちろん、ほとんどのスレッドは何もしていませんでした。マシンが約6500のスレッド(Javaで)に達すると、マシン全体に問題が発生し、不安定になります。

私の経験によると、Java(最近のバージョン)は、コンピューター自体が問題なくホストできるのと同じ数のスレッドを喜んで消費できます。

もちろん、十分なRAMが必要です。また、スレッドが実行しているすべてのことを実行し、各スレッドのスタックを作成するには、十分なメモリを備えたJavaを起動する必要があります。最新のCPU(AMDまたはIntelの最新の数世代)と1〜2ギガのメモリ(OSによって異なる)を備えたマシンは、何千ものスレッドを持つJVMを簡単にサポートできます。

これより具体的な答えが必要な場合は、プロファイリングするのが最善です。


86

ええと、たくさん。

ここにはいくつかのパラメータがあります。特定のVMに加えて、通常はVMにもランタイムパラメータがあります。これはオペレーティングシステムによっていくらか推進されています。基盤となるOSはスレッドに対してどのようなサポートを提供し、スレッドにはどのような制限を課していますか?VMが実際にOSレベルのスレッドを実際に使用している場合、古き良き赤のスレッド/緑のスレッドのことです。

「サポート」の意味は別の質問です。次のようなJavaプログラムを作成した場合

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(そして、構文の詳細について文句を言わないでください、私は最初のコーヒーを飲みます)そして、あなたは確かに数百または数千のスレッドが実行されることを期待するはずです。しかし、作成、スレッドのは比較的コストがかかり、スケジューラのオーバーヘッドは非常に大きくなる可能性があります。それらのスレッドに何か便利なことをさせることができるかどうかは不明です。

更新

はい、抵抗できませんでした。これは、いくつかの装飾を施した、私の小さなテストプログラムです。

public class DieLikeADog {
    private static Object s = new Object();
    private static int count = 0;
    public static void main(String[] argv){
        for(;;){
            new Thread(new Runnable(){
                    public void run(){
                        synchronized(s){
                            count += 1;
                            System.err.println("New thread #"+count);
                        }
                        for(;;){
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e){
                                System.err.println(e);
                            }
                        }
                    }
                }).start();
        }
    }
}

Intel上のOS / X 10.5.6、およびJava 6 5(コメントを参照)では、これは私が手に入れたものです

新しいスレッド#2547
新しいスレッド#2548
新しいスレッド#2549
スレッドを作成できません:5
新しいスレッド#2550
スレッド「メイン」の例外java.lang.OutOfMemoryError:新しいネイティブスレッドを作成できません
        java.lang.Thread.start0(Native Method)で
        java.lang.Thread.start(Thread.java:592)で
        DieLikeADog.main(DieLikeADog.java:6)で

10
どのくらいのメモリでJVMを起動しましたか?それは重要です。
エディ

10
Java 6 update 13、Ubuntu 8.10 32ビット、4Gig ram、デフォルトのJVM設定= 6318スレッド。
スティーブK

9
えっと、スレッドのスタックサイズで遊んでください。java -Xss100kを使用すると、Linuxで19702のスレッドを作成できました。
スティーブK

21
java -Xss50kは約32kのスレッドを取得しました。それは私のラムの4ギグを最大にした。新しいプロセスをフォークしてjavaを殺すために十分なメモリをマシンに戻すために、いくつかの実行中のプロセスを停止する必要がありました;)-良い時間。
スティーブK

21
Windows 7でJava 7を使用して、システムが停止する前に200,000のスレッドを作成しました。タスクマネージャは、8 GBのRAMを使用しているプロセスを示しました。なぜそれがそこで止まったのかはわかりませんが...私のコンピューターには12GBのRAMがあります。したがって、これは他の制限に達している可能性があります。
Dobes Vandermeer

50

Charlie Martinの投稿を読んだ後、ヒープサイズによって作成できるスレッドの数に違いがあるかどうか知りたくて、その結果にまったく驚かされました。

Vista Home Premium SP1でJDK 1.6.0_11を使用して、2 MBから1024 MBのさまざまなヒープサイズでチャーリーのテストアプリケーションを実行しました。

たとえば、2 MBのヒープを作成するには、引数-Xms2m -Xmx2mを指定してJVMを呼び出します。

これが私の結果です:

2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads

つまり、そうです、ヒープサイズは間違いなく重要です。ただし、ヒープサイズと最大スレッド数の関係は、まったく比例しません。

変だ。


11
各スレッドにそのサイズのヒープが与えられている場合は、理にかなっています。
するThorbjörnRavnアンデルセン

1
警告:私のマシンには2583 GBのRAMがありません。またはスワップ。また、JVMはスレッドローカルヒープスペースを割り当てません。それはそれではあり得ない...
benjismith

49
ヒープサイズにより、スタックに使用できるアドレス空間が減少します。256K /スタックのアドレス空間は理にかなっています。
トムホーティン-タックライン2009


39

私はこの質問がかなり古いことを知っていますが、私の発見を共有したいだけです。

私のラップトップは25,000スレッドを生成するプログラムを処理することができ、それらすべてのスレッドは2秒の定期的な間隔でMySqlデータベースにデータを書き込みます。

その間このプログラムを実行し10,000 threadsましたが30 minutes continuously、私のシステムも安定しており、他のプログラムの閲覧、開く、閉じるなど、他の通常の操作を行うことができました。

25,000 threadsシステムslows downが、それは応答のまま。

すぐに50,000 threadsシステムstopped respondingを使用して、手動でシステムを再起動する必要がありました。

私のシステムの詳細は次のとおりです。

Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6

実行する前に、jvm引数を設定します-Xmx2048m

それが役に立てば幸い。


2
「スローダウン」は交換のように聞こえます。
するThorbjörnRavnアンデルセン

ありがとう。それはかなり堅実なマシンであり、突然起動が停止するまで、ほぼ8年間は問題なく動作しました。Windowsの代わりにUbuntuをインストールしたところ、数値が再び処理されるようになりました:)
Shekhar

揚げコア2デュオ、ubuntu調味料付き:D
Pasupathi Rajamanickam

31

理論上絶対最大値は、通常、プロセスのユーザーアドレス空間をスレッドスタックサイズで割ったものです(ただし、実際には、すべてのメモリがスレッドスタック用に予約されている場合、動作するプログラムはありません...)。

たとえば、32ビットのWindowsでは、各プロセスに2GBのユーザーアドレス空間があり、各スレッドに128Kのスタックサイズが割り当てられているため、絶対最大数は16384スレッド(= 2 * 1024 * 1024/128)になると予想されます。実際には、XPで約13,000起動できることがわかりました。

それから、あなたは本質的にあなたが(a)あなたがコード内のその多くのスレッドをうまく操作でき、明らかにばかげたこと(それらをすべて同じオブジェクトで待機させてからnotifyAll()を呼び出すなど)をすることができないかどうかに興味があると思います: (b)オペレーティングシステムができるかどうか。原則として、(a)の回答も「はい」の場合、(b)の回答は「はい」です。

ちなみに、スタックサイズはThreadのコンストラクターで指定できます。このために、VMパラメータをいじる必要はありません(おそらく、その必要はありません)。


1
したがって、64ビットOSを使用してください。現在、64ビットプロセッサを使用しているのはどのくらいですか。
トムホーティン-タックライン2009

確かに、私は理論上の限界と実際の限界の例を挙げています。ちなみに、32ビットマシン(サーバーを含む)は非常にたくさんあります...
Neil Coffey

2

何千ものコア(9000?)のトレードショーで、ある専門のマシンでアプリの1つを実行し、すべてをロードしたClojureの話を聞いたことを思い出します。残念ながら、現在リンクが見つかりません(ヘルプ?)。

これに基づいて、ハードウェアとコードがJVMではなく制限要因であると言っても安全だと思います。


もう一度見てもらえますか?私はそれを見てみたいと思います-興味深いことに聞こえ、関数型言語はコア間で簡単に拡張できることをサポートしています。
するThorbjörnRavnアンデルセン

それへのリンクを提供できますか?Azul SystemsのリードエンジニアであるCliff Click、Jr.が、Azulの最大のJCAシステム(Azul Vega 3シリーズ7300モデル7380D:AzulSystems.Com/products/compute_appliance_specs.htm)で864コアと768を使用してRich HickeyのAntコロニーシミュレーションを実行したことを知っています。GB RAMと700のアリは700コアを最大に管理することができました。しかし、9000コア、それはかなり印象的です。あれはどんな機械?
イェルクWミッターク

それは私が信じている「Ants」シミュレーションでした-これはRich Hickey(Clojure作成者)がこれについて語っているリンクです-blip.tv/clojure/clojure-concurrency-819147。これは、800以上のコアを持ついくつかの大きなAzulシステムボックスで行われ、主に、Clojureがマルチコアの同時実行性をどのように処理するかを示すために行われました。
mikera

@mikera linsは期限切れです。
するThorbjörnRavnアンデルセン

2

CharlieのDieLikeACodeクラスをいじってみたところ、Javaスレッドのスタックサイズは、作成できるスレッド数の大部分を占めているようです。

-XssはJavaスレッドのスタックサイズを設定します

例えば

java -Xss100k DieLikeADog

ただし、JavaにはExecutorインターフェースがあります。私はそれを使用します。何千ものRunnableタスクを送信し、Executorにそれらを固定数のスレッドで処理させることができます。


13
DieLikeACatという名前を付けられますか?あなたがそれを実行するまで、それは死んでも生きていません。
Goodwine 2013

エグゼキューターを指摘していただきありがとうございます。より頻繁に使用してください。ただし、通信を処理する必要がある場合など、Runnable/をCallable実際に継続的に実行する必要がある場合は機能しません。しかし、SQLクエリには最適です。
Matthieu 2014年


0

スレッドの最大数は次の要素によって異なります。

  • マイクロプロセッサ、RAMなどのハードウェア構成。
  • 32ビットか64ビットかなどのオペレーティングシステム
  • runメソッド内のコード。runメソッド内のコードが巨大な場合、シングルスレッドオブジェクトにはより多くのメモリが必要になります。

  • 0

    最新の(systemd)Linuxシステムに関する追加情報。

    調整が必要になる可能性のある値については、多くのリソースがあります(JVMスレッドの最大数を増やす方法(Linux 64ビット)など)。)。ただし、cgroupにpids.maxを設定するsystemd "TasksMax"制限により、新しい制限が課されます。

    ログインセッションの場合、UserTasksMaxのデフォルトはカーネル制限pids_max(通常は12,288)の33%であり、/ etc / systemd / logind.confでオーバーライドできます。

    サービスの場合、DefaultTasksMaxのデフォルトは、カーネル制限pids_max(通常は4,915)の15%です。"systemctl edit"でTasksMaxを設定するか、/ etc / systemd / system.confでDefaultTasksMaxを更新することで、サービスを上書きできます。


    0

    2017年... DieLikeADogクラス。

    新しいスレッド#92459スレッド「メイン」の例外java.lang.OutOfMemoryError:新しいネイティブスレッドを作成できません

    i7-7700 16GB RAM


    オフコースの回答はさまざまです。6 GBのRAMで10278を取得しました。
    jamie

    -4

    スレッドはいくつでも処理できます。制限はありません。映画を見てNetBeansを使用しているときに次のコードを実行し、マシンを停止せずに正常に動作しました。このプログラムよりも多くのスレッドを保持できると思います。

    class A extends Thread {
        public void run() {
            System.out.println("**************started***************");
            for(double i = 0.0; i < 500000000000000000.0; i++) {
                System.gc();
                System.out.println(Thread.currentThread().getName());
            }
            System.out.println("************************finished********************************");
        }
    }
    
    public class Manager {
        public static void main(String[] args) {
            for(double j = 0.0; j < 50000000000.0; j++) {
                A a = new A();
                a.start();
            }
        }
    }

    7
    私はこれが非常に遅いコメントであることを知っていますが、これらの多くのスレッドを開始して実行できた理由は(通常の合理的なシステム構成を想定して)各スレッドが基本的に出力から1行を出力し、それ以上の理由がないためです存在し、すぐに殺されるため、リソースの継続的な可用性が保証されます。
    ucsunil 2014年

    @ucsunilそれは真実ではありません。コードを読み間違えたと思います。私はそれを試してみました、そして異なるスレッドが最初の行だけでなくそれらの名前も印刷しています。つまり、それらはアクティブです。ガベージコレクションが参照されていないスレッドをリサイクルすると考えた場合は、リサイクルしません。こちらを参照してください
    Evgeni Sergeev 2016

    1
    ただし、しばらくmainするOutOfMemoryErrorと、私のマシンにがスローされ、これ以上スレッドを作成できないと言われます。たぶん@AnilPalに気づかなかったでしょう。main(..)エラーをスローした後、新しいスレッドの作成がいつ中止されるかを明確に確認するために、メソッドに別の印刷ステートメントを含めることをお勧めします。
    Evgeni Sergeev 2016

    5
    驚くべき... 実際のチューリングマシンの発見...無限のリソース。
    Josh
    弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
    Licensed under cc by-sa 3.0 with attribution required.