【问题标题】:Java: where do static fields live within the memory?Java:静态字段在内存中的什么位置?
【发布时间】:2011-01-09 16:13:07
【问题描述】:

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

【问题讨论】:

  • 静态字段在第一次调用封闭类型时被初始化,并且可以从该类型的任何实例访问它们。
  • 请记住,静态字段引用的对象只是普通对象,因此任何特定实现如何处理静态字段并不重要。

标签: java class static


【解决方案1】:

静态字段是类变量,在该类的所有实例之间共享。实例变量(或我认为您所指的对象字段)属于类的各个实例并且不共享。

至于它们在内存中的存储位置将取决于 JVM 的实现,并且没有理由要求两个不同的 JVM 按规范将它们存储在同一个位置(至少据我所知) - 应在此处插入适当的规格表链接)。

【讨论】:

    【解决方案2】:

    正如尼克的回答所说,语言规范没有规定特定的“物理”位置,但就您可以推理的逻辑思维模型而言,它可能有助于您将静态字段视为附加到这些字段所属的类的类对象 (Foo.class)。

    顺便说一句,类对象在处理静态实体时以其他方式使用(由语言规范规定):例如,当调用synchronized 静态方法时,锁定在该方法所属的类的类对象上。

    【讨论】:

    • 你的意思是对静态字段的锁定也会锁定类对象吗?
    • @tm.sauron 您不能锁定字段,只能锁定该字段引用的对象(在这种情况下,只有后者被锁定)。如果调用synchronized 的静态方法,它会锁定类对象,因为静态方法没有this 引用。 (非静态 synchronized 方法在调用时锁定 this,而不是类对象。)
    【解决方案3】:

    正如 NickLarsen 所说,我认为没有任何 JVM 规范如何准确存储静态字段。编译定义的常量(静态最终)将很可能在编译期间替换表达式。对于可变静态字段,只有两个选项:堆或(如果存在)JVM 的数据段。

    【讨论】:

      【解决方案4】:

      静态字段是类的一部分;据说,当类被卸载时,它们会消失。将它们想象成接近类的Class 实例是有道理的。 Java 应用程序无法获取有关内存布局的详细信息;作为推论,JVM 规范对这个主题没有任何具体要求。甚至在类卸载时字段的“消失”也无法直接观察到,只能通过 GC 操作,假设放置良好的 finalize() 方法。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2014-05-08
          • 2023-03-07
          • 2020-07-17
          • 2012-08-29
          • 1970-01-01
          • 2010-10-22
          • 2016-06-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多