Java:静态字段存储在内存中的哪里?

20

如果我们将对象存储在对象的静态字段中,JVM如何为其分配内存?它是否存在于“隐式”(不确定我是否使用了正确的单词)类对象中?静态字段与对象字段有何不同?


静态字段在第一次调用封闭类型时初始化,并且可以从该类型的任何实例访问。 - Ritwik Bose
请记住,由静态字段引用的对象只是普通对象,因此任何特定实现如何处理静态字段并不太重要。 - Tom Hawtin - tackline
5个回答

15

静态字段是类变量,它们在该类的所有实例之间共享。实例变量(或者我认为你所指的对象字段)属于类的各个实例,不会被共享。

至于它们在内存中的存储位置将基于JVM的实现方式,按规范没有理由要求两个不同的JVM将它们存储在同一位置上(据我所知 - 在此应插入适当的规范说明链接)。


7
正如Nick的回答所说,语言规范没有指定特定的“物理”位置,但从你可以推理的逻辑心理模型来看,静态字段可以被视为附加到属于这些字段所属类的类对象 (Foo.class)。另外,当处理静态实体时,类对象以其他方式使用(这些方式是由语言规范规定的):例如,当调用synchronized静态方法时,锁定保持在该方法所属类的类对象上。

你的意思是对静态字段进行锁定也会锁定类对象吗? - Twaha Mehmood
1
@tm.sauron 你不能锁定一个字段,只能锁定该字段所引用的对象(在这种情况下,只有后者被锁定)。如果你调用一个被synchronized修饰的静态方法,它会锁定类对象,因为静态方法没有this引用。(非静态的synchronized方法在调用时锁定this而不是类对象。) - C. K. Young

1
正如NickLarsen所说,我认为没有JVM规范说明静态字段的存储方式。编译定义的常量(static final)很可能会在编译时替换表达式。对于变量静态字段,只有两个选项:堆或(如果存在)JVM的数据段。

1

静态字段是类的一部分;据说,它们在类被卸载时消失。可以想象它们就在该类的Class实例附近。关于内存布局的详细信息超出了Java应用程序的范围;因此,JVM规范对此没有任何具体要求。即使在类被卸载时字段“消失”也不能直接观察到,只能通过GC操作来观察,假设有一个放置得当的finalize()方法。


0

静态字段存储在Class对象中,该对象保存在PermGen空间中。这是堆内存的一部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接