Czy istnieje jedna maszyna JVM na aplikację Java?

91

Czy ta sama maszyna JVM jest używana przez wszystkie uruchomione aplikacje Java, czy też ma zastosowanie „jedna maszyna JVM na aplikację Java”? (powiedzmy, że aplikacje to IntelliJ IDEA, na przykład serwer i NetBeans)

Ponadto czy istnieje powiązanie między przypisanymi maszynami JVM a procesami używanymi przez każdą aplikację Java?

nadh
źródło
2
To świetne pytanie. :)
jamie

Odpowiedzi:

81

Ogólnie rzecz biorąc, każda aplikacja otrzyma własną instancję JVM i swój własny proces na poziomie systemu operacyjnego, a każda instancja JVM jest od siebie niezależna.

Istnieją pewne szczegóły implementacji, takie jak współdzielenie danych klasy , gdzie wiele instancji JVM może współdzielić niektóre dane / pamięć, ale nie mają one widocznego dla użytkownika wpływu na aplikacje (z wyjątkiem skrócenia czasu uruchamiania, miejmy nadzieję).

Typowy scenariusz to jednak pojedynczy serwer aplikacji (lub „serwer WWW”), taki jak Glassfish lub Tomcat, na którym działa wiele aplikacji internetowych. W takim przypadku wiele aplikacji internetowych może współużytkować maszynę JVM.

Joachim Sauer
źródło
21

Na każdą aplikację Java przypada jedna maszyna JVM. Nie powinno być między nimi żadnego połączenia, chyba że je utworzysz, np. Za pomocą sieci. Jeśli pracujesz w środowisku IDE, kod, który piszesz, zwykle działa w osobnej JVM. IDE zazwyczaj łączy oddzielną maszynę JVM w celu debugowania. Jeśli masz do czynienia z wieloma aplikacjami internetowymi, mogą one współużytkować tę samą maszynę JVM, jeśli zostaną wdrożone w tym samym kontenerze internetowym.

WhiteFang34
źródło
12

Teoretycznie można uruchamiać wiele aplikacji w JVM. W praktyce mogą na różne sposoby przeszkadzać sobie nawzajem. Na przykład :

  • JVM ma jeden zestaw System.in/ out/ err, jedno domyślne kodowanie, jedno domyślne ustawienie regionalne, jeden zestaw właściwości systemowych i tak dalej. Jeśli jedna aplikacja je zmieni, wpłynie to na wszystkie aplikacje.
  • Każda aplikacja, która wywołuje, System.exit()zabija wszystkie aplikacje.
  • Jeśli jeden wątek aplikacji oszaleje i zużyje zbyt dużo procesora lub pamięci, wpłynie to również na inne aplikacje.
Rajneesh Mishra
źródło
8

Liczba uruchomionych maszyn JVM to liczba wywoływanych plików wykonywalnych. Każda taka aplikacja wywołuje swój własny plik wykonywalny Java (java.exe / javaw.exe etx dla systemu Windows), co oznacza, że ​​każda z nich działa w oddzielnej maszynie JVM.

d-live
źródło
8

Krótka odpowiedź: często tak, otrzymasz jedną aplikację na JVM. Długa odpowiedź: w ten sposób można wykorzystać maszynę JVM i to może być najlepsza opcja, ale nie musi.

Wszystko zależy od tego, co uznasz za „wniosek”. IDE jest dobrym przykładem aplikacji, która jest prezentowana użytkownikom końcowym (tj. Nam) jako pojedyncza jednostka, ale w rzeczywistości składa się z wielu aplikacji bazowych (kompilatory, programy uruchamiające testy, narzędzia do analizy statycznej, programy do pakowania, menedżery pakietów, projekty / narzędzia do zarządzania zależnościami itp.). W takim przypadku istnieje wiele sztuczek, których IDE używa, aby zapewnić, że użytkownik doświadczy zintegrowanego doświadczenia, będąc jednocześnie chronionym (do pewnego stopnia) przed indywidualnymi kaprysami podstawowych narzędzi. Jedną z takich sztuczek jest zrobienie pewnych rzeczy w oddzielnej JVM, komunikując się za pośrednictwem plików tekstowych lub narzędzi do debugowania na poziomie aplikacji.

Serwery aplikacji (Wildfly, Glassfish, Websphere, Weblogic itp.) To aplikacje, których racją bytu jest działanie jako kontenery do uruchamiania innych aplikacji. W takim przypadku z jednej perspektywy na aplikację przypada jedna maszyna JVM (tj. Jedna maszyna JVM jest używany do uruchamiania całego serwera aplikacji), ale w rzeczywistości w tej maszynie JVM znajduje się wiele aplikacji, z których każda jest logicznie oddzielona od siebie we własnym module ładującym klasy (co zmniejsza możliwość przypadkowego przesłuchu w procesie).

Tak więc wszystko naprawdę zależy od tego, co uważasz za application. Jeśli mówisz wyłącznie o „rzeczy, która działa, gdy wywoływana jest funkcja 'main ()'”, to patrzysz na jedną aplikację na JVM - gdy system operacyjny uruchamia JVM, JVM uruchamia public static void main()metodę pojedynczej klasy .

Ale gdy aplikacje zaczną się bardziej skomplikować, granice stają się bardziej rozmyte. IDE, takie jak Intellij lub Eclipse, będzie ponownie wykorzystywać wiele tych samych rzeczy, co „javac”, w tej samej lub innej JVM, a także wykonywać inne prace (np. Malowanie ekranu). Użytkownicy aplikacji internetowej na (współdzielonym JVM) serwerze aplikacji mogą w rzeczywistości używać tej samej „podstawowej” aplikacji, która mogłaby być używana lokalnie za pośrednictwem wiersza poleceń.

syzyf
źródło
5

Każda aplikacja, która ma współdzielone biblioteki, będzie współużytkować tę samą kopię tych bibliotek. Java ma sporo współdzielonych bibliotek. Jednak nie zauważysz różnicy, z wyjątkiem części zapisanej pamięci.

Peter Lawrey
źródło
2

Trochę późno tutaj jednak ta informacja może być dla kogoś przydatna. W systemie Linux, jeśli chcesz wiedzieć, ile JVM jest uruchomionych, możesz wypróbować to polecenie

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

pswyświetlić proces, grepprzeszukać proces zawierający "java" i wcpoliczyć zwrócone wiersze

Ram Dwivedi
źródło
0

W rzeczywistości jest to jedno pytanie, na które można uzyskać bardzo mylące odpowiedzi. Mówiąc krótko:

  1. Tak, na proces Java, na JVM.
  2. Środowisko wykonawcze i ProcessBuilder stosują się do tej reguły.
  3. Ładowanie słoików za pomocą refleksji, a następnie wykonanie main nie spowoduje pojawienia się nowej maszyny JVM.
asmitB
źródło