我想不,他们不是,因为每个进程都有自己的内存空间。
但整个JVM实际上是如何工作的呢?对于我发布的每个Java程序,是否在单独的进程中有单独的JVM?在系统中运行的Java程序是否共享任何东西?操作系统和JVM实现之间是否存在差异?我可以使程序共享变量(即直接通过JVM而不是通常的IPC机制)吗?是否有更多异国情调的单进程JVM用于特殊目的?
一般来说,推荐哪些内容可以读取JVM的内容? spec?一些实现的源代码?网站?书?
答案 0 :(得分:26)
在Java中,是静态类成员 在节目中分享?
类由其全名和加载它的类加载器定义。如果同一个类在同一个JVM进程中,并且两个程序通过相同的类加载器加载该类,则静态成员将被共享。类加载规则非常重要。
我想不,他们不是, 因为每个过程都有自己的 记忆空间,当然。
如果您使用两个单独的JVM来启动两个应用程序,那么您是对的。但是以应用程序/ servlet容器为例,例如tomcat:它们通过相同的进程(tomcat主机进程)加载多个应用程序。
但整个JVM是怎么回事 实际上工作?是否有单独的JVM 在每个Java的单独进程中 我推出的节目?做Java 在系统共享中运行的程序 什么都没有?
每次在命令行键入>java -cp...
时,都会创建一个新进程。请记住,当您运行eclipse或使用fork=true
调用ant java任务时,您也会创建新进程。
操作系统和操作系统之间是否存在差异? JVM实现?我可以做 程序共享变量(即。 直接通过JVM而不是 通常的IPC机制)?在那儿 更具异国情调的单进程JVM 特殊目的?
就像海报上说的那样,Terracota等项目可以为您提供便利。这种共享的一般方法是分布式缓存。
答案 1 :(得分:7)
不,JVM之间不存在静态变量。是的,您运行的每个Java应用程序都有一个单独的JVM进程。
在某些实现中,我相信他们可能会共享某些资源(例如JRE类JITted代码的内存),但我不确定。我相信正在进行的工作是为了实现更多共享,但仍然是一种强有力的方式。 (你真的不希望一个JVM崩溃影响其他人。)
不,你不能让程序透明地共享变量。
我相信有关于JVM的书籍,但我不能推荐任何书籍。你可能最好寻找HotSpot白皮书了解详细信息。 This one是一个非常好的起点。
答案 2 :(得分:6)
如果同一个VM上的不同线程使用单独的类加载器,则它们可能有自己的静态类nember实例。
这里的经典示例是Apache Tomcat将不同的Web应用程序分开,尽管lib jar可能对所有应用程序都是通用的。
答案 3 :(得分:2)
取决于实施,但是有些方法可以共享。正在进行改进的工作,并且Sun(通过Apple)在VM实例之间共享数据方面做了大量工作。有一个链接讨论了其中一些here。
要进行任何类型的共享需要VM实现者执行此操作,您作为程序员无法做任何事情来实现它。
答案 4 :(得分:2)
如果要跨JVM共享变量,可以查看集群产品,如Terracotta。它们将自己称为“网络附加内存”,并允许您使用复制技术跨JVM共享对象引用。
答案 5 :(得分:1)
你的假设是正确的。是的,每个JVM都是一个单独的过程。您可以在运行两个Java程序时打开任务管理器来确认这一点(按名称排序进程并查找java.exe或javaw.exe)。
可以使JVM相互连接(例如,使用本地套接字),但内置任何内容都没有。
答案 6 :(得分:1)
为了继续Kevin提到的内容,我所知道的JVM实现没有允许您跨JVM实例共享静态变量。正如先前的答案所述(正确地) - 每个JVM实例都是它自己的过程。
Terracotta(这是一种集群技术,而不是JVM)允许跨JVM进程边界任意共享对象实例 - 包括共享静态变量。因而绰号“网络附加内存”。出于所有意图和目的,当在JVM进程中使用Terracotta技术时,所有VM中的所有线程都表现得好像它们都在查看单个大型共享堆。 (当然有一些警告,因为这在物理上是不可能的,Terracotta通过复杂的共享和复制算法来管理它,这些算法涉及网络io来移动数据 - 所以有时候延迟和吞吐量不会与本机内存访问相比)
Terracotta网站的Cookbook部分有丰富的例子 - 我建议你从Hello Clustered Instance Recipe开始,以了解它是如何工作的。