Javaアプリケーションごとに1つのJVMがありますか?


91

実行中のすべてのJavaアプリケーションで同じJVMが使用されていますか、それとも「Javaアプリケーションごとに1つのJVM」が適用されますか?(たとえば、アプリケーションはIntelliJ IDEA、サーバー、NetBeansなどです)

さらに、割り当てられたJVMと各Javaアプリケーションによって使用されるプロセスの間には何らかの関係がありますか?


2
これは素晴らしい質問です。:)
jamie

回答:


81

一般的に言えば、各アプリケーションは独自のJVMインスタンスと独自のOSレベルのプロセスを取得し、各JVMインスタンスは互いに独立しています。

Class Data Sharingなどの実装の詳細がいくつかあります。複数のJVMインスタンスが一部のデータ/メモリを共有する可能性がありますが、それらはアプリケーションにユーザーに見える影響を与えません(起動時間の改善を除くと)。

ただし、一般的なシナリオは、複数のWebアプリケーションを実行するGlassfishやTomcatなどの単一のアプリケーションサーバー(または「Webサーバー」)です。この場合、複数のWebアプリケーションがJVMを共有できます。


21

Javaアプリケーションごとに1つのJVMがあります。ネットワークなどを使用して接続を確立しない限り、それらの間には接続があってはなりません。IDE内で作業している場合、作成したコードは通常、別のJVMで実行されます。IDEは通常、デバッグのために個別のJVMを接続します。複数のWebアプリケーションを扱っている場合、同じWebコンテナーにデプロイされていれば、同じJVMを共有できます。


12

理論的には、JVMで複数のアプリケーションを実行できます。実際には、さまざまな方法で相互に干渉する可能性があります。たとえば、次のとおりです。

  • JVMには1セットのSystem.in/ out/err、1つのデフォルトエンコーディング、1つのデフォルトロケール、1つのセットのシステムプロパティなどがあります。1つのアプリケーションがこれらを変更すると、すべてのアプリケーションに影響します。
  • を呼び出すアプリケーションSystem.exit()はすべてのアプリケーションを強制終了します。
  • 1つのアプリケーションスレッドがワイルドになり、CPUまたはメモリを消費しすぎると、他のアプリケーションにも影響を及ぼします。

8

実行中のJVMの数は、呼び出された実行可能ファイルの数です。このような各アプリケーションは、独自のJava実行可能ファイル(Windowsの場合はjava.exe / javaw.exe etx)を呼び出します。これは、それぞれが個別のJVMで実行されていることを意味します。


8

短い答え:多くの場合、はい、JVMごとに1つのアプリケーションを取得します。長い答え:JVMはそのように使用でき、それが最良のオプションかもしれませんが、そうである必要はありません。

それはすべて、あなたが「アプリケーション」であると考えるものに依存します。IDEは、単一のエンティティとしてエンドユーザー(つまり、私たち)に提示されるアプリケーションの良い例ですが、実際には、複数の基本的なアプリケーション(コンパイラ、テストランナー、静的分析ツール、パッケージャ、パッケージマネージャ、プロジェクト/依存関係管理ツールなど)。その場合、ユーザーが統合されたエクスペリエンスを体験すると同時に、基盤となるツールの個々の変化から(ある程度)保護されるようにするために、IDEが使用するさまざまなトリックがあります。そのようなトリックの1つはテキストファイルまたはアプリケーションレベルのデバッグ機能を介して通信する、別のJVMでことことです。

アプリケーションサーバー(Wildfly、Glassfish、Websphere、Weblogicなど)は、その存在理由が他のアプリケーションを実行するコンテナーとして機能するアプリケーションです。その場合、1つの観点から、アプリケーションごとに1つのJVM(つまり、1つのJVM)があります。アプリケーションサーバー全体を実行するために使用されます)が、実際にはそのJVM内に複数のアプリケーションが独自に含まれ、それぞれが独自のクラスローダーで論理的に分離されています(偶発的なインプロセスクロストークの可能性を低減します)。

ですから、すべては本当にあなたが何であるかを考えることに依存していますapplication。「「main()」が呼び出されたときに実行されるもの」について純粋に話している場合は、JVMごとに1つのアプリケーションが表示されます。OSがJVMを起動すると、JVMは単一のクラスのpublic static void main()メソッドを実行します。

しかし、アプリケーションがより複雑になり始めると、境界がぼやけてきます。IntellijやEclipseなどのIDEは、「javac」と同じものの多くを同じJVMまたは別のJVMで再利用し、さまざまな作業(画面の再描画など)を行います。また、(共有JVM)アプリケーションサーバー上のWebアプリケーションのユーザーは、コマンドラインを介してローカルで使用できるものと同じ「コア」アプリケーションを実際に使用している可能性があります。


5

ライブラリを共有しているアプリケーションは、それらのライブラリの同じコピーを共有します。Javaにはかなりの量の共有ライブラリがあります。ただし、節約されたメモリを除いて、違いに気付くことはありません。


2

ここで少し遅れましたが、この情報は誰かにとって役立つかもしれません。Linuxシステムで、実行中のJVMの数を知りたい場合は、このコマンドを試すことができます

$ ps -ef | grep "[j]ava" | wc -l

psプロセスをリストし、grep「java」を含むプロセスを検索し、wc返された行をカウントする


0

実際、これは非常に混乱する答えになる可能性がある1つの質問です。それを本当に短く保つために:

  1. はい、Javaプロセスごと、JVMごと。
  2. RuntimeとProcessBuilderはこのルールに従います。
  3. リフレクションを使用してjarをロードしてからメインを実行しても、新しいJVMは生成されません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.