【问题标题】:GC static object references to nullGC 静态对象对 null 的引用
【发布时间】:2016-10-06 08:59:57
【问题描述】:

我明白了:

  • 无效的本地引用比实际的 GC 收集更有用(它不会产生真正的区别)
  • 静态引用引用的对象在 Classloader 自己收集之前是不合格的(因为它引用了 Class 对象,而后者又引用了静态变量)

当将对象的静态引用显式设置为 null 时,在幕后实际发生了什么?
最初存储在堆中的原始对象会发生什么?

【问题讨论】:

  • 清空本地引用可以作为一个警告,即代码是由并不真正了解自己在做什么的人编写的。否则它没有任何优势。
  • Nullifying local references is more useful for readability than actual GC collection (it won't make a real difference)---它可以区分 OutOfMemoryError 和无错误。
  • 一个常见的误解是认为当一个对象变得无法访问(也就是垃圾)时会发生一些事情。事实是对于普通对象什么都不会发生。内存管理通过复制或压缩 仍然可访问 对象来工作,因此仅包含垃圾的内存区域本身可以被视为空闲内存,而无需显式释放操作。
  • @Holger 谢谢,您的答案实际上是最有用的答案,可以更清楚地解释该过程。不知道为什么很少这样解释,因为这是 imo 最好的说明。
  • 它通常被认为是一个实现细节(嗯,它是一个实现细节,但是是最广泛的实现的一个细节……)或者过于复杂而无法进行介绍。 This document 虽然已经过时,但很好地概述了不同的算法。

标签: java garbage-collection


【解决方案1】:

从对象的角度来看,对它的引用是来自静态字段还是来自其他地方并不重要。一旦不再引用它,它就有资格进行垃圾收集。它何时真正被垃圾回收取决于它所在的对象池,以及所使用的垃圾回收策略。

【讨论】:

  • 谢谢,我想多了。
【解决方案2】:

“幕后”这两点之间没有显着差异。

不同的效果仅仅是由于引用本身的生命周期。一旦不再在方法中使用局部变量,或者最迟在方法退出时,局部变量就会超出范围。静态字段与类一样长,在许多情况下与应用程序的生命周期一样长。

这意味着在大多数情况下(尽管有例外),本地引用不太可能显着延长对象的生命周期,而静态引用会在对象寿命很短的情况下显着延长。

【讨论】:

    【解决方案3】:

    使本地引用无效对可读性更有用

    如果您的意思是它使代码变得混乱并降低了可读性,那么我同意。

    ...不会有真正的不同

    我在一些罕见的情况下,它可以有所作为。但不要这样做,除非你完全确定它很重要(如果你觉得每百种方法不止一次,那可能是错误的)。

    当将对象的静态引用显式设置为 null 时,在幕后实际发生了什么?

    没什么特别的。如果这是最后一次引用,则该对象有资格进行 GC。但这与所有其他对象/引用相同。

    最初存储在堆中的原始对象会发生什么?

    什么都没有,因为它只是被无效的引用。该对象在某一天被收集(如果它是最后一个引用),但同样:没什么特别的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 2021-02-28
      • 1970-01-01
      • 2013-02-26
      • 1970-01-01
      相关资源
      最近更新 更多