说我有obj = new myobject()
,其中obj
被声明为另一个非静态类实例中的静态类字段。一段时间后,我在相同的静态变量obj
上创建了一个新的myobject,从而“覆盖”了原始分配。
这是我的问题:
...其中
obj
被声明为另一个非静态类实例中的静态类字段。
这可能意味着两件事之一; static
字段或static
类的实例字段。
以下内容适用于两种情况,除非另有说明。
1)假定已无法从其他任何地方访问分配的对象实例,GC是否会可靠地释放该对象实例?
这取决于您所说的“可靠”。实际上,不能保证GC会(永远)运行,也不能保证它会在给定的运行中找到所有无法访问的对象,或者不能在程序的生命周期内收集到无法访问的对象。
但是您通常不需要保证这些事情。真正重要的是,不会因为某些无法访问的对象而耗尽堆空间1。
2)如果该字段声明为非静态的,是否有任何区别?
这是我一开始提到的问题所在:
如果我们在谈论一个字段,它是static
类的实例字段,那么它是已经非静态的。
如果我们谈论的是static
字段与实例字段,则各个字段的生存期有所不同。在应用程序的持续时间内,static
字段是可访问的(如果我们忽略动态创建的类加载器)。实例字段的生存时间与其对象所属的对象一样长。
没有任何区别。3]在将静态变量[[2重新分配给新实例之前,将其设置为
null
是否有所不同?
1-我们在这里需要小心一点。 JVM可能由于内存不足或GC花费过多时间收集垃圾而触发“内存不足”事件。在后一种情况下,有可能(至少在理论上)在事件发生之前找不到给定的不可达对象。也可以使用Epsilon收集器运行JVM。该收集器从不收集任何垃圾。
2-注意:您将值分配给变量,而不是相反。您可以还说一个变量被分配一个值。但不是你写的。使用正确的词有助于(您)理解。