每个 Java 应用程序有一个 JVM 吗?

是所有 Java 应用程序都使用相同的 JVM,还是应用“每个 Java 应用程序一个 JVM”?(比如说应用程序是 IntelliJIDEA,一个服务器和 NetBeans)

此外,在分配的 JVM 和每个 Java 应用程序使用的进程之间是否有任何连接?

39542 次浏览

There's one JVM per Java application. There shouldn't be any connection between them unless you establish one, e.g. with networking. If you're working inside of an IDE, the code you write generally runs in a separate JVM. The IDE will typically connect the separate JVM for debugging. If you're dealing with multiple web applications they could share the same JVM if they're deployed to the same web container.

Number of JVMs running is the number of executables invoked. Each such application invokes its own java executable (java.exe/ javaw.exe etx for windows) which means each is running in a separate JVM.

Generally speaking, each application will get its own JVM instance and its own OS-level process and each JVM instance is independent of each other.

There are some implementation details such as Class Data Sharing, where multiple JVM instances might share some data/memory but those have no user-visible effect to the applications (except for improved startup time, hopefully).

A common scenario however is a single application server (or "web server") such as Glassfish or Tomcat running multiple web applications. In this case, multiple web applications can share a JVM.

Any application which has shared libraries will share the same copy of those libraries. Java has a fair amount of shared libraries. However, you won't notice the difference except for some memory saved.

In theory you can run multiple applications in a JVM. In practice, they can interfere with each other in various ways. For example:

  • The JVM has one set of System.in/out/err, one default encoding, one default locale, one set of system properties, and so on. If one application changes these, it affects all applications.
  • Any application that calls System.exit() kills all applications.
  • If one application thread goes wild, and consumes too much CPU or memory it will affect the other applications too.

Little late here however this info may be useful for somebody. In a Linux system, if you want to know how many JVMs are running you can try this command

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

ps to list process, grep to search process containing "java" and wc to count lines returned

Short answer: often, yes, you'll get one application per JVM. Long answer: the JVM can be used that way, and that may be the best option, but it doesn't have to be.

It all depends on what you consider to be an 'application'. An IDE is a good example of an application which is presented to its end users (i.e. us) as a single entity but which is actually comprised of multiple underlying applications (compilers, test runners, static analysis tools, packagers, package managers, project / dependency management tools, etc). In that case there are a variety of tricks which the IDE uses to ensure that the user experiences an integrated experience while also being shielded (to some extent) from the individual vagaries of the underlying tools. One such trick is to do some things in a separate JVM, communicating either via text files or via the application-level debugging facilities.

Application servers (Wildfly, Glassfish, Websphere, Weblogic, etc) are applications whose raison d'etre is to act as containers for other applications to run in. In that case, from one perspective, there's a single JVM per application (i.e. one JVM is used to run the entire application server) but there are actually multiple applications contained within that JVM in their own right, each logically separated from each other in their own classloader (reducing the possibility of accidental in-process crosstalk).

So, it all really depends on what you consider an application to be. If you're purely talking about "the thing which runs when 'main()' is called", then you're looking at one application per JVM - when the OS starts the JVM, the JVM runs a single class's public static void main() method.

But once your applications start getting more complicated your boundaries become more blurred. An IDE such as Intellij or Eclipse will reuse much of the same stuff as 'javac', either in the same JVM or a different one, as well as doing different work (such as repainting the screen). And users of a web application on a (shared JVM) application server may actually be using much the same 'core' application as could be used locally via the command line.

Actually this is one question that can have very confusing answers. To keep it real short:

  1. Yes per java process, per JVM.
  2. Runtime and ProcessBuilder follow this rule.
  3. Loading jars using reflection and then executing the main won't spawn new JVM.