例如:
class A {
static int i=0;
static int j;
static void method() {
// static k=0; can't use static for local variables only final is permitted
// static int L;
}
}
这些变量将存储在 Java 中的什么位置,是堆内存还是栈内存?它们是如何储存的?
原文由 Nav 发布,翻译遵循 CC BY-SA 4.0 许可协议
静态方法(实际上是所有方法)以及静态变量都存储在堆的
PermGen
部分,因为它们是反射数据的一部分(类相关数据,而不是实例相关数据)。从 Java 8 开始,PermGen 已被 MetaSpace 取代,并且根据 JEP 122 ,它仅保存元数据,而静态字段存储在堆中。请注意,这主要适用于 Oracle 的 Hotspot JVM 和其他基于它的。但是,并非每个 JVM 都像 Eclipse OpenJ9 那样具有 PermGen 或 Metaspace 。
_更新澄清_:
请注意,只有变量及其技术值(基元或引用)存储在 PermGen 空间中。
如果您的静态变量是对对象的引用,则该对象本身存储在堆的正常部分(年轻/老一代或幸存者空间)中。这些对象(除非它们是类等内部对象) 不 存储在 PermGen 空间中。
例子:
关于垃圾收集的一句话:
不要 依赖
finalize()
因为它不能保证运行。完全由 JVM 决定何时运行垃圾收集器以及收集什么,即使对象符合垃圾收集条件。当然,您可以将静态变量设置为 null,从而删除对堆上对象的引用,但这并不意味着垃圾收集器 将 收集它(即使没有更多引用)。
另外
finalize()
只运行一次,所以你必须确保它不会抛出异常或以其他方式阻止对象被收集。如果您通过某些异常停止完成,finalize()
将不会在同一对象上再次调用。_最后一点_:代码、运行时数据等的存储方式取决于所使用的 JVM,即 HotSpot 的存储方式可能与 JRockit 不同,这甚至可能在同一 JVM 的不同版本之间有所不同。以上内容基于 HotSpot for Java 5 和 6(它们基本相同),因为在回答时我会说大多数人都使用这些 JVM。由于 Java 8 内存模型的重大变化,上面的陈述可能不适用于 Java 8 HotSpot - 而且我没有检查 Java 7 HotSpot 的变化,所以我 想 上面的内容仍然适用于该版本,但我在这里不确定。