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

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

我读了一篇SOpost,但无法在那里得到答案。 每个Java应用程序有一个JVM吗?

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

(我假设您正在讨论通过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,但密钥隔离function(如干净地杀死隔离区)实际上是不可能实现的。 或者至少,这是我的观点。

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

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

那么一些像Chrome这样的应用程序甚至会进一步创建多个进程来隔离不同的选项卡和插件。

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

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

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

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

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

用于隔离执行上下文。

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

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

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

Java应用程序服务器(如JBoss)旨在在一个JVM中运行许多应用程序

这取决于您的应用程序。

Waratek 在单个JVM中提供托管多个Java应用程序只需检查一下。