jvm 在Java中,静态类成员在程序之间共享吗?

uhry853o  于 2023-01-05  发布在  Java
关注(0)|答案(8)|浏览(375)

我想不会,因为每个进程都有自己的内存空间。

但是整个JVM是如何工作的呢?对于我启动的每个Java程序,是否都有一个单独的JVM在一个单独的进程中?在一个系统中运行的Java程序是否共享任何东西?操作系统和JVM实现之间是否有区别?我是否可以 * 使 * 程序共享变量(即直接通过JVM而不是通常的IPC机制)?是否有更奇特的用于特殊目的的单进程JVM?
一般来说,关于JVM的核心,推荐阅读哪些内容?spec?一些实现的源代码?网站?书籍?

zujrkrfu

zujrkrfu1#

在Java中,静态类成员在程序之间共享吗?
类由它的全名和加载它的类加载器定义。如果同一个类在同一个JVM进程中,并且两个程序通过同一个类加载器加载该类,那么静态成员是共享的。类加载规则是非常重要的。
我想不会的,因为每个进程都有自己的内存空间。
如果您使用两个单独的JVM来启动两个应用程序,那么您是正确的,但是以应用程序/servlet容器(例如tomcat)为例:它们通过同一进程(Tomcat主机进程)加载若干应用程序。
但是整个JVM究竟是如何工作的呢?对于我启动的每个Java程序,是否在一个单独的进程中有一个单独的JVM?在一个系统中运行的Java程序是否共享任何东西?
每次你在命令行输入>java -cp...,你就创建了一个新的进程,记住当你运行eclipse或者用fork=true调用一个ant java任务时,你也在创建新的进程。
操作系统和JVM实现之间有什么区别吗?我可以让程序共享变量吗(即直接通过JVM而不是通常的IPC机制)?有没有更奇特的单进程JVM用于特殊目的?
就像一个海报上说的,有一些像Terracota这样的项目可以为你提供便利。这种共享的一个通用方法是分布式缓存。

voj3qocg

voj3qocg2#

不,静态变量不在JVM之间。是的,您运行的每个Java应用程序都有一个单独的JVM进程。
在某些实现中,我相信它们可能会共享一些资源(例如JRE类的JITted代码的内存),但我不确定。我相信有正在进行的工作来实现更多的共享,但仍然是以一种健壮的方式。(你不会真的希望一个JVM崩溃影响到其他JVM。)
不,你不能让程序透明地共享变量。
我相信有一些关于JVM的书,但我不能推荐任何一本。您可能最好查找HotSpot白色以了解详细信息。This one是一个很好的起点。

lx0bsm1f

lx0bsm1f3#

如果你的主要兴趣是关于静态类成员是如何示例化的,你可能应该在类加载方面搜索更多。
如果同一VM上的不同线程使用不同的类加载器,则它们可能有自己的静态类成员示例。
这里的经典例子是Apache Tomcat将不同的web应用程序分开,尽管lib jar可能对所有应用程序都是通用的。

jutyujz0

jutyujz04#

这取决于实现方式,但是确实有一些共享的方式。目前正在/曾经正在进行改变这一点的工作,Sun(通过苹果)在VM示例之间共享数据方面做了大量工作。有一个链接讨论了一些here
要进行任何类型的共享都需要VM实现者来完成,而作为程序员,您无法做任何事情来实现它。
VM规范是here,也有一些(更老的)关于它的书。你也可以看看Kaffe的源代码,它很小。

whitzsjs

whitzsjs5#

如果您希望跨JVM共享变量,可以考虑Terracotta这样的集群产品,它们将自己称为“网络附加内存”,允许您使用复制技术跨JVM共享对象引用。

iq0todco

iq0todco6#

你的假设是正确的。是的,每个JVM都是一个独立的进程。当你运行两个Java程序时,你可以通过打开任务管理器来确认这一点(按名称对进程排序,并查找java.exe或javaw.exe)。
可以使JVM相互连接(例如,使用本地套接字),但没有内置任何东西。

ecfdbz9o

ecfdbz9o7#

继续Kevin提到的内容,据我所知,没有JVM实现允许您在JVM示例之间共享静态变量。正如前面的回答所述(正确)-每个JVM示例都是它自己的进程。
赤陶(这是一种集群技术,而不是JVM)允许跨JVM进程边界任意共享对象示例-包括共享静态变量。因此,绰号“网络附加内存”。对于所有意图和目的,当在JVM进程中使用Terracotta技术时,所有VM中的所有线程的行为就像它们都在查看单个大型共享堆。(当然,需要注意的是,因为这在物理上是不可能的,Terracotta通过复杂的共享和复制算法来管理它,这些算法涉及网络IO来移动数据--因此,有时候延迟和吞吐量无法与本地内存访问相比)
Terracotta站点的Cookbook部分有大量的示例--我建议您从Hello Clustered Instance Recipe开始,了解它是如何工作的。

mzsu5hc0

mzsu5hc08#

是的,静态变量仅在运行于相同JVM、具有相同类名以及具有相同包结构的应用程序之间共享。
就像如果,我有两个项目**“A”“B”,项目“A”在src下有包,如(com.azoop.eagle)和项目“B”也具有与上述相同的项目结构(com.azoop.eagle)并且具有相同的类名“Example.java”,包含与“static String logFile="./resource/sms.log”相同的静态变量。那么,如果两个项目都在同一JVM示例中运行,则只有它们将共享相同的静态变量值。由于静态变量在项目的整个生命周期中只加载一次,因此,在此之后,如果不进行修改,它们将共享相同的值。仅当两个类应由同一ClassLoader加载时,才会发生这种情况在两个项目中。
当我有两个不同的Web项目时,我就遇到了这个问题,但是它们运行在相同的
'WebServer'(JBOSS 7.3)**下,并且具有上面解释的相同情况。

相关问题