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

Java 为什么每个应用程序有一个JVM?,java,jvm,Java,Jvm,我了解到每个应用程序都在自己的JVM中运行。为什么会这样?为什么他们不让一个JVM运行2个或更多的应用程序 我读了一篇文章,但没有找到答案。 我说的是通过公共静态void main(String[])方法启动的应用程序…用于隔离执行上下文 如果其中一个进程挂起或失败,或者其安全性受到威胁,其他进程不会受到影响 我认为有单独的运行时也有助于GC,因为它要处理的引用比完全处理的引用要少 此外,为什么要在一个JVM中运行它们呢?(我假设您谈论的是通过公共静态void main(String[])方

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

我读了一篇文章,但没有找到答案。


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

用于隔离执行上下文

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

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

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

(我假设您谈论的是通过
公共静态void main(String[])
方法启动的应用程序…)

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

  • JVM有一组System.in/out/err、一个默认编码、一个默认语言环境、一组系统属性,等等。如果一个应用程序更改了这些,则会影响所有应用程序
  • 任何调用System.exit()的应用程序都会杀死所有应用程序
  • 如果一个应用程序线程失控,并消耗过多的CPU或内存,它也会影响其他应用程序
总之,有很多问题。人们努力使这项工作成功,但从未真正取得成功。一个例子是图书馆,尽管这个项目已经安静了约10年。是另一个例子,尽管他们(实际上我们)通过黑客攻击核心Java类(如Java.lang.System)来“欺骗”,使每个应用程序都获得了System.in/out/err、系统属性等的独立版本1


1-这(“proclets”)应该是一个临时黑客,等待使用真正的“隔离物”的适当解决方案。但是隔离支持停止了,主要是因为JNode架构使用了单个地址空间,没有明显的方式来分离“系统”和“用户”内容。因此,虽然我们可以创建与隔离API相匹配的API,但关键的隔离功能(如干净地杀死隔离体)实际上是不可能实现的。至少,这是/是我的观点。

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

有一个JVM预应用程序的原因,基本上相同,每个应用程序都有OS进程。 下面是为什么每个应用程序都有一个进程的几个原因

  • 应用程序错误不会导致共享同一进程的其他应用程序中的数据关闭/损坏
  • 系统资源按进程计算,因此按应用程序计算
  • 终止进程将自动释放所有相关资源(应用程序可能无法自行清理,因此共享进程可能会产生资源泄漏)
一些应用程序,比如Chrome,甚至可以进一步创建多个进程来隔离不同的标签和插件

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

  • 堆大小越大,堆空间维护代价越高。多个较小的独立堆更易于管理
  • 在JVM中卸载“应用程序”是相当困难的(即使它没有运行,也有许多微妙的原因让它留在内存中)
  • JVM有很多调优选项,您可能需要为应用程序定制这些选项
尽管有几种情况,但JVM实际上是在应用程序之间共享的:

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

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

这取决于您的应用程序


Waratek提供的只是检查一下。

这是web应用程序而不是一般应用程序。@StephenC-一般应用程序与web应用程序有什么不同,特别是在这个问题的上下文中?@AppleLinder-请参阅我的答案。web应用程序是您使用web浏览器与之交谈的应用程序。好吧,那么java中的沙箱与您所说的有一定关系吗?@AppleGrinder称之为“沙箱”听起来有点过火。在一个单独的操作系统进程中运行每个程序就像沙箱一样简单。。。我不确定我会称之为沙箱,因为它们有办法相互干扰,但这不是默认设置。@desert69:你说什么??请检查我的评论就在你的答案上。谢谢和问候。@AjayBhojak我想我不太理解你的评论。你能澄清一下吗?Thanks@desert可以我也发现它令人困惑。:-。所以我想说的是,只有一个应用程序在运行,那就是Jboss。现在,我们创建的应用程序只是单个JVM的一部分。现在,如果我们想访问这些应用程序,我们只需访问JBoss(JVM)提供的服务即可。如果我仍然缺少其他地方,请更正我或添加一些有用的内容。谢谢和问候。