是否所有运行的Java应用程序都使用相同的JVM,或者“每个Java应用程序一个JVM”是否适用?(例如,应用程序是IntelliJ IDEA,服务器和NetBeans)
此外,分配的JVM与每个Java应用程序使用的进程之间是否存在任何联系?
Answers:
一般而言,每个应用程序将获得其自己的JVM实例和其自己的OS级进程,并且每个JVM实例彼此独立。
有一些实现细节,例如Class Data Sharing,其中多个JVM实例可能共享一些数据/内存,但是这些实例对应用程序没有用户可见的影响(希望可以缩短启动时间,但希望如此)。
但是,常见的情况是运行多个Web应用程序的单个应用程序服务器(或“ Web服务器”),例如Glassfish或Tomcat。在这种情况下,多个Web应用程序可以共享一个JVM。
理论上,您可以在JVM中运行多个应用程序。实际上,它们可以以各种方式相互干扰。例如:
- JVM具有一组
System.in
/out
/err
,一种默认编码,一种默认语言环境,一套系统属性,等等。如果一个应用程序更改了这些设置,它将影响所有应用程序。- 任何调用的应用程序都会
System.exit()
杀死所有应用程序。- 如果一个应用程序线程失效,并且消耗过多的CPU或内存,也会影响其他应用程序。
简短的答案:通常,是的,每个JVM您将获得一个应用程序。长答案:JVM可以这样使用,这可能是最好的选择,但并非必须如此。
这完全取决于您认为什么是“应用程序”。IDE是一个很好的应用示例,它可以作为一个实体呈现给最终用户(即我们),但实际上包含多个基础应用(编译器,测试运行器,静态分析工具,打包器,包管理器,项目/依赖管理工具等)。在那种情况下,IDE可以使用多种技巧来确保用户体验到集成的体验,同时(在某种程度上)不受底层工具的各种变化的影响。一种这样的技巧是在单独的JVM中做一些事情,通过文本文件或通过应用程序级调试工具进行通信。
应用程序服务器(Wildfly,Glassfish,Websphere,Weblogic等)是应用程序,其存在的理由是充当其他应用程序在其中运行的容器。在这种情况下,从一个角度来看,每个应用程序只有一个JVM(即一个JVM)用于运行整个应用程序服务器),但实际上该JVM本身包含多个应用程序,每个应用程序在各自的类加载器中在逻辑上彼此分开(减少了意外进程内串扰的可能性)。
因此,这实际上取决于您认为是什么application
。如果您纯粹是在谈论“调用'main()'时将运行的事物”,那么您正在针对每个JVM查看一个应用程序-当操作系统启动JVM时,JVM将运行单个类的public static void main()
方法。
但是,一旦您的应用程序开始变得更加复杂,您的界限就会变得更加模糊。诸如Intellij或Eclipse之类的IDE将在相同的JVM或不同的JVM中重用许多与“ javac”相同的东西,并执行不同的工作(例如重新绘制屏幕)。而且,(共享JVM)应用程序服务器上的Web应用程序的用户实际上可能使用与通过命令行在本地使用的相同的“核心”应用程序。