为什么每个应用程序有一个JVM?

时间:2012-11-24 07:06:07

标签: java jvm

我读到每个应用程序都在自己的JVM中运行。为什么会这样?为什么他们不让一个JVM运行2个或更多应用程序?

我读了一篇SO帖子,但无法在那里得到答案。 Is there one JVM per Java application?

我在谈论通过public static void main(String [])方法启动的应用程序......)

5 个答案:

答案 0 :(得分:27)

(我假设您正在讨论通过public static void main(String[])方法启动的应用程序...)

理论上,您可以在JVM中运行多个应用程序。在实践中,它们可以以各种方式相互干扰。例如:

  • JVM有一组System.in/out/err,一个默认编码,一个默认语言环境,一组系统属性,依此类推。如果一个应用程序更改了这些,则会影响所有应用程序。
  • 任何调用System.exit()的应用程序都会杀死所有应用程序。
  • 如果一个应用程序线程过时,并且消耗太多CPU或内存,它也会影响其他应用程序。

简而言之,存在很多问题。人们努力做到这一点,但他们从未真正成功过。一个例子是Echidna库,尽管该项目已经安静了大约10年。 JNode是另一个例子,虽然他们(实际上我们)通过破解核心Java类(如java.lang.System)来“欺骗”,以便每个应用程序都获得了看似独立版本的System.in/out/err ,系统属性等 1

1 - 这个(“proclets”)应该是一个临时黑客,等待使用真正的“隔离”的正确解决方案。但隔离支持停滞不前,主要是因为JNode架构使用单个地址空间而没有明显的方法来分离“系统”和“用户”的东西。因此,虽然我们可以创建与隔离API匹配的API,但实际上不可能实现密钥隔离功能(如干净地杀死隔离区)。或者至少,这是我的观点。

答案 1 :(得分:6)

有一个JVM预应用程序的原因,基本相同,每个应用程序都有操作系统进程。 以下是为每个应用程序设置流程的几个原因。

  • 应用程序错误不会导致共享同一进程的其他应用程序中的数据损坏/损坏。
  • 系统资源按每个流程计算,因此每个应用程序。
  • 终止进程将自动释放所有相关资源(应用程序可能无法自行清理,因此共享进程可能会导致资源泄漏)。

一些应用程序(如Chrome)甚至可以进一步创建多个进程来隔离不同的选项卡和插件。

说到Java,没有更多理由不共享JVM。

  • 堆大小时堆空间维护损失较高。多个较小的独立堆更易于管理。
  • 在JVM中卸载“应用程序”是相当困难的(即使它没有运行,它还有许多微妙的原因留在内存中)。
  • JVM有很多调整选项,您可能希望为应用程序定制。

虽然有几种情况,JVM实际上是在应用程序之间共享的:

  • 应用程序服务器和servlet容器(例如Tomcat)。服务器端Java规范在设计时考虑了共享服务器JVM和动态加载/卸载应用程序。
  • 很少尝试为CLI应用程序创建共享JVM实用程序(例如nailgun

但实际上,即使在服务器端java中,由于上述原因,每个应用程序通常最好使用JVM(或几个)。

答案 2 :(得分:2)

用于隔离执行上下文。

如果其中一个进程挂起或失败,或者安全性受到威胁,则其他进程不会受到影响。

我认为拥有单独的运行时也有助于GC,因为它的处理引用比完全没有。

此外,为什么要在一个JVM中运行它们?

答案 3 :(得分:1)

Java应用服务器,如JBoss,设计用于在一个JVM中运行许多应用程序

答案 4 :(得分:1)

这取决于您的申请。

Waratek提供Hosting multiple Java applications within a single JVM只需检查一下。