在哪里是一个静态方法和一个静态variables存储在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; } }
这些variables将存储在java(堆栈或堆)中以及如何存储。
静态方法(实际上所有方法)以及静态variables都存储在堆的PermGen
部分,因为它们是reflection数据的一部分(与类相关的数据,与实例无关)。
澄清更新 :
请注意,只有variables及其技术值(基元或参考)存储在PermGen空间中。
如果您的静态variables是对象的引用,则该对象本身存储在堆的正常部分(年轻/旧一代或幸存空间)中。 这些对象(除非它们是像类这样的内部对象) 不存储在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决定何时运行垃圾收集器以及收集什么东西,即使对象是垃圾收集的可用资源也是如此。
当然,你可以设置一个静态variables为null,从而删除对堆上的对象的引用,但这并不意味着垃圾收集器将收集它(即使没有更多的引用)。
此外finalize()
只运行一次,所以你必须确保它不会抛出exception,否则会阻止收集对象。 如果通过某个exception终止了finalize()
,那么finalize()
将不会再次在同一个对象上被调用。
最后一点 :如何存储代码,运行时数据等取决于所使用的JVM,即HotSpot可能与JRockit不同,它可能在相同的JVM版本之间有所不同。 以上是基于HotSpot for Java 5和6(基本上是相同的),因为在回答的时候我会说大多数人使用这些JVM。 由于Java 8的内存模型发生了重大变化,上述语句可能不适用于Java 8 HotSpot – 我没有检查Java 7 HotSpot的变化,所以我想上面的版本仍然是这样的,但我不确定。
类variables(静态variables)存储为与该类关联的Class object
一部分。 这个Class对象只能由JVM创build并存储在permanent generation
。
也有人回答说,它被存储在非堆区域,这被称为Method Area.
即使这个答案是没有错的。 Permgen Area是否是堆的一部分,这只是一个有争议的话题。 很显然,每个人的看法都不一样。 在我看来,我们在JVM参数中提供了不同的堆空间和permgen空间。 所以对它们进行不同的处理是一个很好的假设。
另一种方法来看看它
内存池由JVM内存pipe理器在运行时创build。 内存池可能属于堆或非堆内存。运行时常量池是类文件中constant_pool表的每类或每界面运行时表示。 每个运行时常量池都从Java虚拟机的方法区域分配,静态variables存储在此方法区域中。 实际上,方法区域是烫发的一部分( 参考 )
这是一个简单的答案和一个啰嗦的答案。
简单的答案是堆。 类和适用于类的所有数据(不是实例数据)都存储在堆的永久生成部分。
长的答案已经在堆栈溢出:
JVM中的内存和垃圾收集有一个完整的描述,以及更简洁的说明。
它存储在由类定义引用的堆中。 如果你仔细想一下,它和堆栈没有关系,因为没有范围。
除了Thomas的回答之外,静态variables被存储在称为方法区域的非堆区域中。
静态variables存储在堆中
由于静态variables是类级variables,它们将存储堆内存的“ 永久代 ”。 请查看这个 JVM的更多细节。 希望这会有所帮助