GC在重新分配的静态对象引用上

问题描述 投票:0回答:1

说我有obj = new myobject(),其中obj被声明为另一个非静态类实例中的静态类字段。一段时间后,我在相同的静态变量obj上创建了一个新的myobject,从而“覆盖”了原始分配。

这是我的问题:

  1. 假定已从其他任何地方都无法访问已分配的对象实例,GC是否已可靠地释放它?
  2. 如果该字段声明为非静态的,是否有任何区别?
  3. 在将静态变量重新分配给新实例之前将其设置为null是否有区别?
object reference static garbage-collection
1个回答
0
投票

...其中obj被声明为另一个非静态类实例中的静态类字段。

这可能意味着两件事之一; static字段或static类的实例字段。

以下内容适用于两种情况,除非另有说明。

1)假定已无法从其他任何地方访问分配的对象实例,GC是否会可靠地释放该对象实例?

这取决于您所说的“可靠”。实际上,不能保证GC会(永远)运行,也不能保证它会在给定的运行中找到所有无法访问的对象,或者不能在程序的生命周期内收集到无法访问的对象。

但是您通常不需要保证这些事情。真正重要的是,不会因为某些无法访问的对象而耗尽堆空间1

2)如果该字段声明为非静态的,是否有任何区别?

这是我一开始提到的问题所在:

  • 如果我们在谈论一个字段,它是static类的实例字段,那么它是已经非静态的。

  • 如果我们谈论的是static字段与实例字段,则各个字段的生存期有所不同。在应用程序的持续时间内,static字段是可访问的(如果我们忽略动态创建的类加载器)。实例字段的生存时间与其对象所属的对象一样长。

3]在将静态变量[[2重新分配给新实例之前,将其设置为null是否有所不同?

没有任何区别。


1-我们在这里需要小心一点。 JVM可能由于内存不足或GC花费过多时间收集垃圾而触发“内存不足”事件。在后一种情况下,有可能(至少在理论上)在事件发生之前找不到给定的不可达对象。也可以使用Epsilon收集器运行JVM。该收集器从不收集任何垃圾。

2-注意:您将值分配给变量,而不是相反。您可以还说一个变量被分配一个值。但不是你写的。使用正确的词有助于(您)理解。

© www.soinside.com 2019 - 2024. All rights reserved.