静态变量是在程序执行的整个持续时间内分配的,因此不会叠加 也不是堆很方便。那它在哪里?应该有一些装载的地方?
答案 0 :(得分:30)
我们的记忆中有3个部分:
堆栈段 - 包含局部变量和引用变量(保存堆中对象地址的变量)。
堆段 - 包含运行时中的所有已创建对象,仅包含对象及其对象属性(实例变量)。
代码段 - 加载时实际编译的Java字节码所在的段。 静态成员(变量或方法)称为类成员,这意味着它们位于类(字节码)所在的位置,即代码段中。
答案 1 :(得分:18)
静态字段在加载类时初始化,并在卸载该类的类加载器时被丢弃。它们可以被清理,甚至可以在另一个类加载器中复制。
对于那些使用OSGi的应用程序,静态变量不能在应用程序的生命周期中存活多次。
这是如何实现的可能是依赖于JVM的,但Sun / Oracle JVM创建了一个“对象”来保存类的静态字段。此对象可通过Unsafe类访问,该类也可用于检查此“对象”字段。
答案 2 :(得分:8)
静态变量是在程序执行的整个持续时间内分配的,因此堆栈和堆都不方便。
实际上,静态帧(即保存静态变量的帧)是从堆中分配的。
并且在程序执行期间它们不一定存在。例如,如果父类加载器,所有类和所有实例都无法访问,则动态加载的类的静态帧可以被垃圾收集。
答案 3 :(得分:1)
来自http://www.daniweb.com/software-development/java/threads/34695:
分配静态变量的内存 在该计划的开始,在 常规内存,而不是堆栈 (专门为记忆留出的记忆 程序)。这样做的好处是 它使你的变量或 程序完全不变,而你 不能意外改变价值。 这样做的缺点是 直到内存才被释放 程序终止。我从来没有 听到了静态价值所带来的一切 比它们更多的记忆 定期宣布,但他们的记忆 使用是不变的。
答案 4 :(得分:1)
在JVM使用的五个内存区域中,当在准备和加载阶段由Application类加载器加载类时,静态字段在Class Area(PremGen的一部分)中分配内存。 如果该字段是原始字段,则该值存储在类区域中,如果它是Object类型(使用的是新运算符),则它存储在堆中,但引用将被赋予类区域中指定的静态字段变量。 卸载类时,该静态字段的内存也可以由GC进行垃圾回收。
如果该字段也是最终字段,即static final,则它保存在类区域下的常量池中。
答案 5 :(得分:0)
将静态变量提供给与代码存储在同一存储段(即类区域)中的内存。它独立于内存的堆栈或堆段。在程序的整个过程中,它仍然可以访问。