例如:
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,堆或堆栈内存中存储在哪里?它们如何存储?
例如:
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,堆或堆栈内存中存储在哪里?它们如何存储?
Answers:
静态方法(实际上是所有方法)以及静态变量都存储在PermGen
堆部分中,因为它们是反射数据(与类相关的数据,与实例无关的数据)的一部分。
更新说明:
请注意,只有变量及其技术值(原始或引用)存储在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的版本之间甚至可能有所不同。上面的内容基于适用于Java 5和6的HotSpot(它们基本相同),因为在回答之时,我会说大多数人都使用了这些JVM。由于Java 8的内存模型发生了重大变化,因此上述声明可能不适用于Java 8 HotSpot,并且我没有检查Java 7 HotSpot的更改,因此我想以上对于该版本仍然适用,但我不确定在这里。
类变量(静态变量)作为Class object
与该类关联的一部分存储。该Class对象只能由JVM创建,并存储在中permanent generation
。
也有人回答说,它存储在称为“非堆”的区域中。Method Area.
即使这个回答也没有错。Permgen Area是否是堆的一部分,这只是一个有争议的话题。显然,每个人的看法不同。我认为我们在JVM参数中提供堆空间和permgen空间的方式有所不同。因此,以不同的方式对待它们是一个很好的假设。
另一种观看方式
内存池是由JVM内存管理器在运行时创建的。内存池可以属于堆内存,也可以属于非堆内存。运行时常量池是类文件中constant_pool表的按类或按接口运行时间表示。每个运行时常量池都从Java虚拟机的方法区域分配,并且静态变量存储在此方法区域中。此外,非堆无非是烫发根area.Actually方法面积烫发根的一部分。(参考)
Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
在Java 8之前:
静态变量存储在permgen空间(也称为方法区域)中。
PermGen Space用于存储3件物品
从Java 8开始
静态变量存储在Heap本身中。从Java 8开始删除了PermGen Space,并引入了名为MetaSpace的新空间,与以前的Permgen Space不再是Heap的一部分。元空间位于本机内存(由操作系统提供给特定应用程序以供其自身使用的内存)中,并且现在仅存储类元数据。
插入的字符串和静态变量将移入堆本身。
有关官方信息,请参阅:JEP 122:移除永久基因空间
这是一个带有简单答案和冗长答案的问题。
简单的答案是堆。类和应用于类的所有数据(不是实例数据)存储在堆的Permanent Generation部分中。
长答案已经在堆栈溢出中:
JVM中对内存和垃圾回收有一个详尽的描述,并给出了一个更为简洁的答案。
它存储在类定义所引用的堆中。如果您考虑一下,它与堆栈无关,因为没有作用域。