2011-07-04 89 views
19

静态变量分配给整个程序执行期间,所以堆栈 和堆都不方便。那它在哪里?应该有一些地方加载?什么是静态变量的实际内存位置?

+2

另请参阅:http://www.daniweb.com/software-development/java/threads/34695 – mnicky

+0

@mnicky谢谢!这是有帮助的。 – Reuben

+0

[其中是一个静态方法和存储在java中的静态变量。在堆或堆栈内存中](http://stackoverflow.com/questions/8387989/where-is-a-static-method-and-a-static-variable-stored-in-java-in-heap-or- in-sta) –

回答

15

当一个类被加载时,静态字段被初始化,而当该类的类加载器被卸载时,被放弃。它们可以被清理,甚至可以在另一个类加载器中复制。

对于那些使用OSGi的应用程序来说,静态变量在应用程序的整个生命周期中都不会生效,可以多次重新加载。

实现方式可能与JVM有关,但Sun/Oracle JVM会创建一个“对象”来存放类的静态字段。这个对象可以通过Unsafe类访问,它也可以用来检查这个“objects”字段。

1

http://www.daniweb.com/software-development/java/threads/34695

的静态变量的存储器是在节目的开始分配 ,在 常规存储器,而不是堆栈 (存储器用于 程序预留​​特异性)。这样做的好处是 它使你的变量或 程序完全不变,而你 不会意外地改变这个值。 这样做的缺点是, 内存不会被释放,直到 程序终止。我从来没有听说过任何静态值取 任何更多的内存,如果他们是 定期申报,但他们的内存 使用是恒定的通过。

+1

-1:“完全不变”?你在想“终结”吗?并且内存不会被释放直到结束;这不是一个缺点,这就是'静态'的全部意义! –

+1

@OliCharlesworth,他在谈论“静态final”变量。与不必这样做相比,被迫更长时间地使用更多内存是不利的。 – Pacerier

7

静态变量分配给整个程序执行期间,所以堆栈和堆都不方便。

实际上,静态帧(即保存静态变量的帧)是从堆中分配的。

它们不一定在程序执行期间存在。例如,如果父类加载器,所有类和所有实例都变得无法访问,则可以垃圾收集动态加载的类的静态帧。

24

我们必须在我们的记忆3段:

  1. 堆栈段—包括局部变量和参考变量(即持有对象的地址在堆中变量)。

  2. 堆段—包含运行时所有创建的对象,只包含对象及其对象属性(实例变量)。

  3. 代码段—加载时实际编译的Java字节码所在的段。 静态成员(变量或方法)被称为类成员,这意味着它们驻留在代码段中的类(字节码)所在的位置。

+6

这个答案已经投了这么多,但与http://stackoverflow.com/questions/3849634/static-allocation-in-java-heap-stack-and-permanent-generation/3849819#3849819 – ravindrab

+3

Sourav矛盾,你能请给你的消息来源? –

+1

也许Sourav指的是C++? – flow2k

1

缺货的该JVM使用五个存储区,静态字段在等级地区(PremGen的一部分)当类由应用程序的类加载器准备并装载阶段期间加载分配的内存。 如果该字段是原始字段,则该值存储在类区域中,如果该字段属于对象类型(使用新操作符),则将其存储在堆中,但引用会被分配给类区域中分配的静态字段变量。 当类被卸载时,该静态字段的内存也可以被GC垃圾收集。

如果该字段也是最终字段,即static final,则它会保留在类区域下的常量池中。

相关问题