【问题标题】:Java static instances and referencesJava 静态实例和引用
【发布时间】:2023-04-02 19:25:01
【问题描述】:

我有一个单身课程。 还有一个类使用单例实例。如下:

class A {
    SingletonDemo obj = SingletonDemo.getInstance() ;
. 
. 
. 
} 

现在我知道 SingletonDemo 类中 SingletonDemo 的实例的生命周期是程序的生命周期。

但是 obj 在 A 类中的生命周期呢? 当控制从 A 类退出时它会被垃圾收集还是会在整个程序的生命周期中存在?

【问题讨论】:

  • 它不是 A 类中的新对象,只是指向同一个单例 obj 的引用。
  • 你的问题真的没有意义。 SingletonDemo obj 字段是对单例的reference。如果您正确实现了单例模式,那么将只有 一个 实例,正如您所说,它将在程序的整个生命周期中持续存在。
  • 您的意思是将obj 声明为静态的吗?
  • 是的,从第一次调用getInstance() 到 Jvm 死亡,单例保持不变。但是用户类对对象的引用会进出范围。
  • 那么引用会怎样呢?内存映射中有一个部分分配给“obj”以指向静态实例,对吗?

标签: java reference garbage-collection singleton static-members


【解决方案1】:
  • Java 规范规定obj in class A 的范围是A 的整个主体:

在类类型 C(第 8.1.6 节)中声明或继承的成员 m 的声明范围是 C 的整个主体,包括任何嵌套类型声明。 见JLS 6.3

这意味着如果控制退出类 A,引用 obj 将被垃圾回收。

  • 单例实例是否会在程序的整个生命周期中存在,取决于它是否被使用(它有一个引用)。如果不再使用/引用,则可以将其卸载。以下是规范中的说明:

Java 编程语言的实现可以卸载类。一种 当且仅当其定义的类加载器可能被卸载时,类或接口才可能被卸载 由垃圾收集器回收,如 §12.6 中所述。见Unloading Classes and Interfaces

如果我理解正确的话,一个类是一个单例,意味着整个应用程序中只有一个实例,但这并不意味着如果它根本不被引用,它将在应用程序的生命周期内可用。

【讨论】:

    【解决方案2】:

    现在我知道SingletonDemo里面的实例的生命周期 SingletonDemo 类适用于程序的生命周期。

    这部分问题就是答案。

    因为下面这行不是创建一个新对象,它只是创建了一个class A 的引用属性,它引用了 SingleTon 对象。

     SingletonDemo obj = SingletonDemo.getInstance() ;
    

    所以obj 对 SingleTon 的生命周期没有影响。

    【讨论】:

    • @DownVoter,请解释一下这个答案有什么问题!
    【解决方案3】:

    您可以将A.obj 想象成一段内存——内存的一部分保存A 类的实例——它保存了对SingletonDemo 实例的引用

    obj 本身不能被垃圾收集;它指向的 SingletonDemo 实例可能会在不再存在对它的强引用时被垃圾收集(即永远不会用于单例)。

    A类的实例被垃圾回收时,存储obj引用的内存被丢弃。

    【讨论】:

      【解决方案4】:

      obj 只是对SingletonDemo 类中相同静态实例的引用。只有当两个引用都不再可用时,才会对对象进行垃圾回收。由于SingletonDemo 类中的引用是静态的,所以它会一直保留在内存中直到程序退出。

      【讨论】:

        猜你喜欢
        • 2018-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-29
        • 2023-03-10
        • 1970-01-01
        • 2012-07-10
        相关资源
        最近更新 更多