Java中的静态方法和静态变量存放在哪里?

新手上路,请多包涵

例如:

 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 许可协议

阅读 2.1k
2 个回答

静态方法(实际上是所有方法)以及静态变量都存储在堆的 PermGen 部分,因为它们是反射数据的一部分(类相关数据,而不是实例相关数据)。从 Java 8 开始,PermGen 已被 MetaSpace 取代,并且根据 JEP 122 ,它仅保存元数据,而静态字段存储在堆中。

请注意,这主要适用于 Oracle 的 Hotspot JVM 和其他基于它的。但是,并非每个 JVM 都像 Eclipse OpenJ9 那样具有 PermGen 或 Metaspace

_更新澄清_:

请注意,只有变量及其技术值(基元或引用)存储在 PermGen 空间中。

如果您的静态变量是对对象的引用,则该对象本身存储在堆的正常部分(年轻/老一代或幸存者空间)中。这些对象(除非它们是类等内部对象) 存储在 PermGen 空间中。

例子:

 static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.

关于垃圾收集的一句话:

不要 依赖 finalize() 因为它不能保证运行。完全由 JVM 决定何时运行垃圾收集器以及收集什么,即使对象符合垃圾收集条件。

当然,您可以将静态变量设置为 null,从而删除对堆上对象的引用,但这并不意味着垃圾收集器 收集它(即使没有更多引用)。

另外 finalize() 只运行一次,所以你必须确保它不会抛出异常或以其他方式阻止对象被收集。如果您通过某些异常停止完成, finalize() 将不会在同一对象上再次调用。

_最后一点_:代码、运行时数据等的存储方式取决于所使用的 JVM,即 HotSpot 的存储方式可能与 JRockit 不同,这甚至可能在同一 JVM 的不同版本之间有所不同。以上内容基于 HotSpot for Java 5 和 6(它们基本相同),因为在回答时我会说大多数人都使用这些 JVM。由于 Java 8 内存模型的重大变化,上面的陈述可能不适用于 Java 8 HotSpot - 而且我没有检查 Java 7 HotSpot 的变化,所以我 上面的内容仍然适用于该版本,但我在这里不确定。

原文由 Thomas 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 Java 8 之前:

静态变量存储在permgen空间(也称为方法区)。

PermGen 空间也称为方法区

PermGen Space 用来存储 3 个东西

  1. 类级别数据(元数据)
  2. 实习字符串
  3. 静态变量

从 Java 8 开始

静态变量存储在堆本身中。从 Java 8 开始,PermGen 空间已被删除,并引入了名为 MetaSpace 的新空间,与以前的 Permgen 空间不同,它不再是堆的一部分。元空间存在于本机内存(操作系统为特定应用程序提供的内存供其自己使用)上,现在它只存储类元数据。

驻留的字符串和静态变量被移入堆本身。

官方信息参考: JEP 122:Remove the Permanent Gen Space

原文由 Manish Kumar 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题