Gibt es eine JVM pro Java-Anwendung?

91

Wird dieselbe JVM von allen ausgeführten Java-Anwendungen verwendet oder gilt "eine JVM pro Java-Anwendung"? (Angenommen, die Anwendungen sind IntelliJ IDEA, ein Server und beispielsweise NetBeans.)

Gibt es außerdem eine Verbindung zwischen zugewiesenen JVMs und Prozessen, die von jeder Java-Anwendung verwendet werden?

nadh
quelle
2
Das ist eine gute Frage. :)
Jamie

Antworten:

80

Im Allgemeinen erhält jede Anwendung eine eigene JVM-Instanz und einen eigenen Prozess auf Betriebssystemebene, und jede JVM-Instanz ist unabhängig voneinander.

Es gibt einige Implementierungsdetails wie die gemeinsame Nutzung von Klassendaten , bei denen mehrere JVM-Instanzen möglicherweise Daten / Speicher gemeinsam nutzen, diese jedoch keine für den Benutzer sichtbaren Auswirkungen auf die Anwendungen haben (mit Ausnahme einer hoffentlich verbesserten Startzeit).

Ein häufiges Szenario ist jedoch ein einzelner Anwendungsserver (oder "Webserver") wie Glassfish oder Tomcat, auf dem mehrere Webanwendungen ausgeführt werden. In diesem Fall können mehrere Webanwendungen eine JVM gemeinsam nutzen.

Joachim Sauer
quelle
20

Es gibt eine JVM pro Java-Anwendung. Es sollte keine Verbindung zwischen ihnen bestehen, es sei denn, Sie stellen eine her, z. B. mit dem Netzwerk. Wenn Sie innerhalb einer IDE arbeiten, wird der von Ihnen geschriebene Code im Allgemeinen in einer separaten JVM ausgeführt. Die IDE verbindet normalerweise die separate JVM zum Debuggen. Wenn Sie mit mehreren Webanwendungen arbeiten, können diese dieselbe JVM verwenden, wenn sie in demselben Webcontainer bereitgestellt werden.

WhiteFang34
quelle
12

Theoretisch können Sie mehrere Anwendungen in einer JVM ausführen. In der Praxis können sie sich auf verschiedene Weise gegenseitig stören. Zum Beispiel :

  • Die JVM verfügt über einen Satz System.in/ out/ err, eine Standardcodierung, ein Standardgebietsschema, einen Satz Systemeigenschaften usw. Wenn eine Anwendung diese ändert, wirkt sich dies auf alle Anwendungen aus.
  • Jede Anwendung, die aufruft, beendet System.exit()alle Anwendungen.
  • Wenn ein Anwendungsthread wild wird und zu viel CPU oder Speicher verbraucht, wirkt sich dies auch auf die anderen Anwendungen aus.
Rajneesh Mishra
quelle
8

Die Anzahl der ausgeführten JVMs entspricht der Anzahl der aufgerufenen ausführbaren Dateien. Jede solche Anwendung ruft ihre eigene ausführbare Java-Datei auf (java.exe / javaw.exe etx für Windows), was bedeutet, dass jede in einer separaten JVM ausgeführt wird.

d-live
quelle
8

Kurze Antwort: Oft erhalten Sie eine Anwendung pro JVM. Lange Antwort: Die JVM kann auf diese Weise verwendet werden, und das ist vielleicht die beste Option, muss es aber nicht sein.

Es hängt alles davon ab, was Sie als "Anwendung" betrachten. Eine IDE ist ein gutes Beispiel für eine Anwendung, die ihren Endbenutzern (dh uns) als eine Einheit präsentiert wird, aber tatsächlich aus mehreren zugrunde liegenden Anwendungen besteht (Compiler, Testläufer, statische Analysetools, Packager, Paketmanager, Projekt / Tools für das Abhängigkeitsmanagement usw.). In diesem Fall gibt es eine Vielzahl von Tricks, mit denen die IDE sicherstellt, dass der Benutzer eine integrierte Erfahrung erfährt und gleichzeitig (in gewissem Maße) vor den einzelnen Unwägbarkeiten der zugrunde liegenden Tools geschützt ist. Ein solcher Trick besteht darin, einige Dinge in einer separaten JVM zu erledigen und entweder über Textdateien oder über die Debugging-Funktionen auf Anwendungsebene zu kommunizieren.

Anwendungsserver (Wildfly, Glassfish, Websphere, Weblogic usw.) sind Anwendungen, deren Ziel es ist, als Container für andere Anwendungen zu fungieren. In diesem Fall gibt es aus einer Perspektive eine einzelne JVM pro Anwendung (dh eine JVM) wird verwendet, um den gesamten Anwendungsserver auszuführen. Es sind jedoch tatsächlich mehrere Anwendungen in dieser JVM enthalten, die jeweils in ihrem eigenen Klassenladeprogramm logisch voneinander getrennt sind (wodurch die Möglichkeit eines versehentlichen Übersprechens während des Prozesses verringert wird).

Es hängt also wirklich davon ab, was Sie für eine applicationhalten. Wenn Sie nur über "das Ding sprechen, das ausgeführt wird, wenn 'main ()' aufgerufen wird", dann sehen Sie sich eine Anwendung pro JVM an - wenn das Betriebssystem die JVM startet, führt die JVM die public static void main()Methode einer einzelnen Klasse aus .

Sobald Ihre Anwendungen jedoch komplizierter werden, verschwimmen Ihre Grenzen. Eine IDE wie Intellij oder Eclipse verwendet einen Großteil des gleichen Materials wie 'javac' entweder in derselben oder einer anderen JVM und führt unterschiedliche Arbeiten aus (z. B. das Neulackieren des Bildschirms). Benutzer einer Webanwendung auf einem (gemeinsam genutzten JVM-) Anwendungsserver verwenden möglicherweise tatsächlich dieselbe Kernanwendung, die lokal über die Befehlszeile verwendet werden kann.

Sisyphus
quelle
5

Jede Anwendung mit gemeinsam genutzten Bibliotheken verwendet dieselbe Kopie dieser Bibliotheken. Java hat eine ganze Reihe von gemeinsam genutzten Bibliotheken. Sie werden den Unterschied jedoch nur bemerken, wenn Speicherplatz gespeichert ist.

Peter Lawrey
quelle
2

Etwas spät hier kann diese Information jedoch für jemanden nützlich sein. Wenn Sie in einem Linux-System wissen möchten, wie viele JVMs ausgeführt werden, können Sie diesen Befehl ausführen

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

psProzess grepauflisten, Prozess mit "Java" suchen und zurückgegebene wcZeilen zählen

Ram Dwivedi
quelle
0

Eigentlich ist dies eine Frage, die sehr verwirrende Antworten haben kann. Um es kurz zu machen:

  1. Ja, pro Java-Prozess, pro JVM.
  2. Runtime und ProcessBuilder folgen dieser Regel.
  3. Das Laden von Jars mithilfe von Reflection und das anschließende Ausführen des Mains führen nicht zu einer neuen JVM.
asmitB
quelle