在 Java 中,静态类成员是否在程序之间共享?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/686079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Java, are static class members shared among programs?
提问by Hanno Fietz
I imagine that no, they aren't, because every process has its own memory space, of course.
我想不,他们不是,因为当然,每个进程都有自己的内存空间。
But how does the whole JVM thing actually work? Is there a separate JVM in a separate process for every Java program that I launch? Do Java programs running in a system share anything at all? Are there differences between OSs and JVM implementations? Can I makeprograms share variables (i. e. directly through the JVM rather than the usual IPC mechanisms)? Are there more exotic one-process JVMs for special purposes?
但是整个 JVM 是如何工作的呢?对于我启动的每个 Java 程序,在单独的进程中是否有单独的 JVM?系统中运行的 Java 程序是否共享任何内容?操作系统和 JVM 实现之间有区别吗?我可以让程序共享变量吗(即直接通过 JVM 而不是通常的 IPC 机制)?是否有更多奇特的单进程 JVM 用于特殊用途?
Generally, what are recommendable reads about the guts of JVMs? The spec? The source code of some implementation? Websites? Books?
一般来说,关于 JVM 的胆量有哪些值得推荐的读物?该规范?一些实现的源代码?网站?图书?
回答by Miguel Ping
In Java, are static class members shared among programs?
在 Java 中,静态类成员是否在程序之间共享?
A class is defined by its full name and the class loader that loaded it. If the same class is within the same JVM process and the two programs loaded the class through the same class loader then the static members are shared. Classloading rules are of extreme importance.
一个类由它的全名和加载它的类加载器定义。如果同一个类在同一个 JVM 进程中,并且两个程序通过同一个类加载器加载这个类,那么静态成员是共享的。类加载规则极其重要。
I imagine that no, they aren't, because every process has its own memory space, of course.
我想不,他们不是,因为当然,每个进程都有自己的内存空间。
If you are using two separate JVMs to launch two apps, you are correct. But take the case of application/servlet containers such as tomcat: they load several apps through the same process (the tomcat host process).
如果您使用两个独立的 JVM 来启动两个应用程序,那么您是对的。但是以应用程序/servlet 容器(例如 tomcat)为例:它们通过同一个进程(tomcat 主机进程)加载多个应用程序。
But how does the whole JVM thing actually work? Is there a separate JVM in a separate process for every Java program that I launch? Do Java programs running in a system share anything at all?
但是整个 JVM 是如何工作的呢?对于我启动的每个 Java 程序,在单独的进程中是否有单独的 JVM?系统中运行的 Java 程序是否共享任何内容?
Every time you type >java -cp...at the command line, you are creating a new process. Bear in mind that when you run eclipse or call an ant java task with fork=trueyou are also creating new processes.
每次>java -cp...在命令行键入时,都在创建一个新进程。请记住,当您运行 eclipse 或调用 ant java 任务时,fork=true您也在创建新进程。
Are there differences between OSs and JVM implementations? Can I make programs share variables (i. e. directly through the JVM rather than the usual IPC mechanisms)? Are there more exotic one-process JVMs for special purposes?
操作系统和 JVM 实现之间有区别吗?我可以让程序共享变量吗(即直接通过 JVM 而不是通常的 IPC 机制)?是否有更多奇特的单进程 JVM 用于特殊用途?
Like a poster said, there are projects like Terracota that facilitate this for you. A general approach for this kind of sharing is a distributed cache.
就像海报说的那样,有像 Terracota 这样的项目可以为您提供便利。这种共享的一般方法是分布式缓存。
回答by Jon Skeet
No, static variables aren't between JVMs. Yes, there's a separate JVM process for each Java app you run.
不,静态变量不在 JVM 之间。是的,您运行的每个 Java 应用程序都有一个单独的 JVM 进程。
In some implementations I believe they may share someresources (e.g. memory for JITted code of JRE classes) but I'm not sure. I believe there's ongoing work to enable more sharing, but still in a robust way. (You don't really want one JVM crashing to affect others.)
在某些实现中,我相信它们可能会共享一些资源(例如 JRE 类的 JITted 代码的内存),但我不确定。我相信有正在进行的工作来实现更多的共享,但仍然是一种稳健的方式。(您真的不希望一个 JVM 崩溃影响其他人。)
No, you can't make programs share variables transparently.
不,你不能让程序透明地共享变量。
I believe there are books about the JVM, but I can't recommend any. You'd probably be best off looking for HotSpot white papers for details of that. This oneis a pretty good starting point.
我相信有关于 JVM 的书籍,但我不能推荐任何书籍。您可能最好寻找 HotSpot 白皮书以了解详细信息。这是一个很好的起点。
回答by mkoeller
you should probably search more in the area of class loading if your main interest is about how static class members are instantiated.
如果您的主要兴趣是静态类成员是如何实例化的,那么您可能应该在类加载领域进行更多搜索。
Different threads on the same VM may have their own static class nember instances if they used separate class loaders.
如果同一 VM 上的不同线程使用单独的类加载器,则它们可能具有自己的静态类编号实例。
The classic example here would be Apache Tomcatkeeping different web applications separate, though lib jars might be common to all applications.
这里的经典示例是Apache Tomcat将不同的 Web 应用程序分开,尽管 lib jar 可能对所有应用程序都是通用的。
回答by TofuBeer
Depends on the implementation, but yes there are ways things are shared. There is/was work underway to change that, and Sun (via Apple) has done a lot of work in sharing data between instances of the VM. There is a link that discusses some of that here.
取决于实现,但是有一些方法可以共享。正在/正在进行改变这一点的工作,并且 Sun(通过 Apple)在 VM 实例之间共享数据方面做了大量工作。有一个链接在这里讨论了其中的一些内容。
To do any sort of sharing requires the VM implementor to do it, you as a programmer cannot do anything to make it happen.
进行任何类型的共享都需要 VM 实现者来做,作为程序员,您无法做任何事情来实现它。
The VM spec is here, there are some (older) books about it as well. You can also look at the source for Kaffewhich is pretty small.
回答by Kevin Hakanson
If you want to share variables across JVMs, you could look at clustering products like Terracotta. They refer to themselves as "network attached memory" and let you share object references across JVMs using replication technology.
如果你想在 JVM 之间共享变量,你可以看看像Terracotta这样的集群产品。它们将自己称为“网络附加内存”,并允许您使用复制技术在 JVM 之间共享对象引用。
回答by Michael Myers
You are correct in your assumption. Yes, each JVM is a separate process. You can confirm this by opening Task Manager when you're running two Java programs (sort processes by name and look for java.exe or javaw.exe).
你的假设是正确的。是的,每个 JVM 都是一个单独的进程。您可以通过在运行两个 Java 程序时打开任务管理器来确认这一点(按名称对进程进行排序并查找 java.exe 或 javaw.exe)。
It is possible to make JVMs connect to each other (with local sockets, for instance), but there's nothing built in.
可以让 JVM 相互连接(例如,使用本地套接字),但没有内置任何内容。
回答by Taylor Gautier
Just to follow on to what Kevin mentioned, there are no JVM implementations that I am aware of that allow you to share static variables across JVM instances. As previous answers have stated (correctly) - each JVM instance is it's own process.
只是继续凯文提到的内容,我知道没有 JVM 实现允许您跨 JVM 实例共享静态变量。正如之前的答案(正确)所述 - 每个 JVM 实例都是它自己的进程。
Terracotta (which is a clustering technology, not a JVM) allows for arbitrary sharing of object instances across JVM process boundaries - including sharing static variables. Thus the moniker "network attached memory". For all intents and purposes, when using Terracotta technology in your JVM process, all of the threads in all of the VMs behave as if they were all looking at a single, large, shared heap. (With caveats of course, since that's not physically possible, Terracotta manages it through sophisticated sharing and replication algorithms which involve network io to move data - so therefore there are times when latency and throughput will not compare to native memory access)
Terracotta(它是一种集群技术,而不是 JVM)允许跨 JVM 进程边界任意共享对象实例——包括共享静态变量。因此,绰号“网络附加内存”。出于所有意图和目的,当在您的 JVM 进程中使用 Terracotta 技术时,所有 VM 中的所有线程的行为就好像它们都在查看单个大型共享堆。(当然有警告,因为这在物理上是不可能的,Terracotta 通过复杂的共享和复制算法来管理它,这些算法涉及网络 io 来移动数据 - 因此有时延迟和吞吐量无法与本机内存访问相比)
There are abundant examples in the Cookbook section of the Terracotta site - I recommend you start with the Hello Clustered Instance Recipeto get a feel for how it works.
Terracotta 站点的 Cookbook 部分有大量示例 - 我建议您从 Hello Clustered Instance Recipe开始,以了解它是如何工作的。

