11

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

我读了一个 SO 帖子,但无法在那里得到答案。 每个 Java 应用程序是否有一个 JVM?

我说的是通过公共静态 void main(String[]) 方法启动的应用程序...)

4

5 回答 5

33

(我假设您正在谈论通过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,但关键的隔离功能(如彻底杀死隔离)实际上是不可能实现的。或者至少,那是/是我的观点。

于 2012-11-24T07:18:39.557 回答
6

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

  • 应用程序错误不会降低/损坏共享同一进程的其他应用程序中的数据。
  • 系统资源按进程计算,因此按应用程序计算。
  • 终止进程会自动释放所有关联的资源(应用程序可能不会自己清理,因此共享进程可能会产生资源泄漏)。

好吧,Chrome 等一些应用程序甚至会进一步创建多个进程来隔离不同的选项卡和插件。

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

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

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

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

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

于 2012-11-24T07:32:22.937 回答
3

用于隔离执行上下文。

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

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

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

于 2012-11-24T07:18:22.210 回答
1

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

于 2012-11-24T07:20:13.863 回答
1

这取决于您的应用程序。

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

于 2012-11-24T07:36:20.340 回答