Existe um JVM por aplicativo Java?

91

O mesmo JVM é usado por todos os aplicativos Java em execução ou 'um JVM por aplicativo Java' se aplica? (digamos que os aplicativos sejam IntelliJ IDEA, um servidor e NetBeans, por exemplo)

Além disso, existe alguma conexão entre JVMs atribuídos e processos usados ​​por cada aplicativo Java?

nadh
fonte
2
Esta é uma grande pergunta. :)
jamie de

Respostas:

81

De modo geral, cada aplicativo obterá sua própria instância de JVM e seu próprio processo de nível de sistema operacional e cada instância de JVM é independente uma da outra.

Existem alguns detalhes de implementação, como Class Data Sharing , em que várias instâncias JVM podem compartilhar alguns dados / memória, mas não têm efeito visível para o usuário para os aplicativos (exceto para tempo de inicialização melhorado, espero).

Um cenário comum, entretanto, é um único servidor de aplicativos (ou "servidor da web"), como Glassfish ou Tomcat executando vários aplicativos da web. Nesse caso, vários aplicativos da web podem compartilhar uma JVM.

Joachim Sauer
fonte
21

Existe um JVM por aplicativo Java. Não deve haver nenhuma conexão entre eles, a menos que você estabeleça uma, por exemplo, com rede. Se você estiver trabalhando dentro de um IDE, o código que você escreve geralmente é executado em uma JVM separada. O IDE normalmente conectará a JVM separada para depuração. Se você estiver lidando com vários aplicativos da web, eles podem compartilhar a mesma JVM se forem implementados no mesmo contêiner da web.

WhiteFang34
fonte
12

Em teoria, você pode executar vários aplicativos em uma JVM. Na prática, eles podem interferir uns nos outros de várias maneiras. Por exemplo :

  • A JVM possui um conjunto de System.in/ out/ err, uma codificação padrão, um local padrão, um conjunto de propriedades do sistema e assim por diante. Se um aplicativo alterar isso, afetará todos os aplicativos.
  • Qualquer aplicativo que chama System.exit()elimina todos os aplicativos.
  • Se um thread de aplicativo enlouquecer e consumir muita CPU ou memória, isso afetará os outros aplicativos também.
Rajneesh Mishra
fonte
8

O número de JVMs em execução é o número de executáveis ​​chamados. Cada um desses aplicativos invoca seu próprio executável java (java.exe / javaw.exe etx para Windows), o que significa que cada um está sendo executado em uma JVM separada.

d-live
fonte
8

Resposta curta: geralmente, sim, você obterá um aplicativo por JVM. Resposta longa: a JVM pode ser usada dessa forma, e essa pode ser a melhor opção, mas não precisa ser.

Tudo depende do que você considera ser um 'aplicativo'. Um IDE é um bom exemplo de um aplicativo que é apresentado a seus usuários finais (ou seja, nós) como uma entidade única, mas que na verdade é composto de vários aplicativos subjacentes (compiladores, executores de teste, ferramentas de análise estática, empacotadores, gerenciadores de pacotes, projeto / ferramentas de gerenciamento de dependências, etc). Nesse caso, há uma variedade de truques que o IDE usa para garantir que o usuário experimente uma experiência integrada, ao mesmo tempo em que está protegido (até certo ponto) dos caprichos individuais das ferramentas subjacentes. Um desses truques é fazer algumas coisas em uma JVM separada, comunicando-se por meio de arquivos de texto ou por meio dos recursos de depuração no nível do aplicativo.

Os servidores de aplicativos (Wildfly, Glassfish, Websphere, Weblogic, etc) são aplicativos cuja razão de ser é atuar como contêineres para outros aplicativos serem executados. Nesse caso, de uma perspectiva, há um único JVM por aplicativo (ou seja, um JVM é usado para executar todo o servidor de aplicativos), mas na verdade existem vários aplicativos contidos nessa JVM, cada um logicamente separado um do outro em seu próprio carregador de classe (reduzindo a possibilidade de interferência acidental no processo).

Então, tudo realmente depende do que você considera applicationser. Se você está falando puramente sobre "o que é executado quando 'main ()' é chamado", então você está olhando para um aplicativo por JVM - quando o sistema operacional inicia a JVM, a JVM executa um public static void main()método de classe única .

Mas, uma vez que seus aplicativos começam a ficar mais complicados, seus limites se tornam mais confusos. Um IDE como o Intellij ou Eclipse reutilizará muitas das mesmas coisas que o 'javac', na mesma JVM ou em uma diferente, além de fazer um trabalho diferente (como redesenhar a tela). E os usuários de um aplicativo da web em um servidor de aplicativos (JVM compartilhado) podem, na verdade, estar usando quase o mesmo aplicativo 'núcleo' que poderia ser usado localmente por meio da linha de comando.

sísifo
fonte
5

Qualquer aplicativo que tenha bibliotecas compartilhadas compartilhará a mesma cópia dessas bibliotecas. Java tem uma boa quantidade de bibliotecas compartilhadas. No entanto, você não notará a diferença, exceto por alguma memória salva.

Peter Lawrey
fonte
2

Um pouco tarde aqui, porém, essa informação pode ser útil para alguém. Em um sistema Linux, se você quiser saber quantas JVMs estão em execução, você pode tentar este comando

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

pslistar o processo, greppesquisar o processo contendo "java" e wccontar as linhas retornadas

Ram Dwivedi
fonte
0

Na verdade, essa é uma pergunta que pode ter respostas muito confusas. Para ser bem curto:

  1. Sim, por processo java, por JVM.
  2. O Runtime e o ProcessBuilder seguem esta regra.
  3. Carregar jars usando reflexão e depois executar o principal não gerará um novo JVM.
asmitB
fonte