7

假设您有一个Collection<B>,并且您将要删除一个项目。的实例B引用自 的实例A,并引用 的实例C,如第一张图所示:

图A

现在,由于有一个指向 B 的引用,因此对象被“删除”或垃圾收集是毫无疑问的。它只是从集合中删除,就像这样,对吗?

图B

现在,让我们拥有Collection<A>与以前相同的引用层次结构,并删除 A 的一个实例。

图C

如果没有其他对 的引用A,它不仅会从集合中删除,还会被标记为垃圾。我对吗?那么BC呢?B如果除了引用的实例之外没有其他引用,它们也会变成垃圾C吗?

这是我所面临的简化。我想A从集合中删除一个实例,并且我想确保BC继续使用它。A我不再收藏的地方,所有还活着的“孩子”对我来说都是内存泄漏。

当我看着我制作的这些照片时,这个问题似乎太愚蠢了。但我的情况就没有那么琐碎了。它看起来像这样:

图 4

  • 图中Model层为黄色,ViewModel层为绿色
  • “A ViewModel”类引用了它的A Model
  • 有一个实例A Model集合(在 Model 和 ViewModel 层中都是的子级)B ModelBA
  • 每个B Model“知道它的父级” - 引用它的父级“模型”实例
  • 回到 VM 层,“A ViewModel”包含“B ViemModel”项目的集合
  • 与任何好的 ViewModel 一样,“B ViewModel”引用“B Model”

我有这些A ViewModel实例的集合。当我删除一个时,我需要其他所有东西来配合它。如果对所涉及的任何实例都没有其他“外部引用”(基本上,没有其他箭头从图片外部进入),那么删除的“A ViewModel”实例会带走所有的孩子吗?如果是这样,是否有任何“陷阱”可能使这种简化产生误导?如果我完全错了,为什么?:)

感谢您阅读到这里!

4

1 回答 1

10

如果对所涉及的任何实例都没有其他“外部引用”(基本上,没有其他箭头从图片外部进入),那么删除的“A ViewModel”实例会带走所有的孩子吗?

是的,只要您的代码没有对子项的引用,它将有资格进行垃圾收集,并且最终应该被收集。

如果没有其他对 A 的引用,它不仅会从集合中删除,还会被标记为垃圾。我对吗?

这实际上不是这样的。GC 不会“跟踪垃圾”——相反,它会检查当前正在执行的代码中的所有对象引用,然后走出去寻找当前“活动”的引用。那时剩下的任何东西都不是活着的,然后就有资格被收集。如果在您的图表中到达“B”或“C”的唯一方法是通过“A”的那个实例,并且您从集合中删除“A”,那么所有这些都将有资格获得 GC 并在下一个适当的 GC 收集。

于 2013-11-05T00:25:55.897 回答