回答:
これは、使用しているCPU、OS、他のプロセスが実行していること、使用しているJavaリリース、およびその他の要因によって異なります。マシンを停止する前に、Windowsサーバーのスレッド数が6500を超えることを確認しました。もちろん、ほとんどのスレッドは何もしていませんでした。マシンが約6500のスレッド(Javaで)に達すると、マシン全体に問題が発生し、不安定になります。
私の経験によると、Java(最近のバージョン)は、コンピューター自体が問題なくホストできるのと同じ数のスレッドを喜んで消費できます。
もちろん、十分なRAMが必要です。また、スレッドが実行しているすべてのことを実行し、各スレッドのスタックを作成するには、十分なメモリを備えたJavaを起動する必要があります。最新のCPU(AMDまたはIntelの最新の数世代)と1〜2ギガのメモリ(OSによって異なる)を備えたマシンは、何千ものスレッドを持つJVMを簡単にサポートできます。
これより具体的な答えが必要な場合は、プロファイリングするのが最善です。
ええと、たくさん。
ここにはいくつかのパラメータがあります。特定の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)で
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
つまり、そうです、ヒープサイズは間違いなく重要です。ただし、ヒープサイズと最大スレッド数の関係は、まったく比例しません。
変だ。
私はこの質問がかなり古いことを知っていますが、私の発見を共有したいだけです。
私のラップトップは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
。
それが役に立てば幸い。
理論上の絶対最大値は、通常、プロセスのユーザーアドレス空間をスレッドスタックサイズで割ったものです(ただし、実際には、すべてのメモリがスレッドスタック用に予約されている場合、動作するプログラムはありません...)。
たとえば、32ビットのWindowsでは、各プロセスに2GBのユーザーアドレス空間があり、各スレッドに128Kのスタックサイズが割り当てられているため、絶対最大数は16384スレッド(= 2 * 1024 * 1024/128)になると予想されます。実際には、XPで約13,000起動できることがわかりました。
それから、あなたは本質的にあなたが(a)あなたがコード内のその多くのスレッドをうまく操作でき、明らかにばかげたこと(それらをすべて同じオブジェクトで待機させてからnotifyAll()を呼び出すなど)をすることができないかどうかに興味があると思います: (b)オペレーティングシステムができるかどうか。原則として、(a)の回答も「はい」の場合、(b)の回答は「はい」です。
ちなみに、スタックサイズはThreadのコンストラクターで指定できます。このために、VMパラメータをいじる必要はありません(おそらく、その必要はありません)。
何千ものコア(9000?)のトレードショーで、ある専門のマシンでアプリの1つを実行し、すべてをロードしたClojureの話を聞いたことを思い出します。残念ながら、現在リンクが見つかりません(ヘルプ?)。
これに基づいて、ハードウェアとコードがJVMではなく制限要因であると言っても安全だと思います。
CharlieのDieLikeACodeクラスをいじってみたところ、Javaスレッドのスタックサイズは、作成できるスレッド数の大部分を占めているようです。
-XssはJavaスレッドのスタックサイズを設定します
例えば
java -Xss100k DieLikeADog
ただし、JavaにはExecutorインターフェースがあります。私はそれを使用します。何千ものRunnableタスクを送信し、Executorにそれらを固定数のスレッドで処理させることができます。
Runnable
/をCallable
実際に継続的に実行する必要がある場合は機能しません。しかし、SQLクエリには最適です。
少なくともMac OS X 10.6 32ビットでは、オペレーティングシステムによる制限(2560)があります。このstackoverflowスレッドを確認してください。
最新の(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を更新することで、サービスを上書きできます。
スレッドはいくつでも処理できます。制限はありません。映画を見て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();
}
}
}
main
するOutOfMemoryError
と、私のマシンにがスローされ、これ以上スレッドを作成できないと言われます。たぶん@AnilPalに気づかなかったでしょう。main(..)
エラーをスローした後、新しいスレッドの作成がいつ中止されるかを明確に確認するために、メソッドに別の印刷ステートメントを含めることをお勧めします。