【问题标题】:Does this reference cause a memory leak?此引用是否会导致内存泄漏?
【发布时间】:2011-12-06 09:44:21
【问题描述】:

我有一个 TabControl,每个选项卡都包含一个 TradeBookSetViewModel。由于 Tradebook 会变得非常大,因此用户可以根据需要移除这本书。

在 DeleteBook() 上,我只需从 observablecollection 中删除 TradeBookSetViewModel:

_bookSetViewModels.Remove(oldbook);

然后我创建一个新的 emptyBook 作为占位符并将其插入到相同的选项卡位置。该选项卡看起来仍然像持有交易簿一样,但实际上是空的。

为此,我从 Unity Container 中解析了一个新实例,并将 DisplayName 从 oldBook 复制到 emptyBook。

BookSetViewModel emptyBook = _container.Resolve<BookSetViewModel>();
emptyBook.DisplayName = oldbook.DisplayName;
_bookSetViewModels.Insert(positionOfDisposedTab, emptyBook);

到目前为止一切顺利。

但后来我意识到 emptyBook 也需要 Books 属性。属性 Books 的类型为 Dictionary&lt;string, CustomClassItem&gt;,因此我认为首先我可以做与 DisplayName 相同的事情。

emptyBook.Books = oldbook.Books;

但这是否意味着 emptyBook 将引用 oldBook,因此 oldBook 不能再被垃圾收集?

也许我应该像这样克隆字典:

emptyBook.Books = book.Books.ToDictionary(entry => entry.Key, entry => entry.Value);

目标: 归根结底,我需要 emptyBook 中的 Books 属性不为空,而 oldBook 应该能够被垃圾收集。有什么想法吗?

【问题讨论】:

  • 很确定它仍然会被垃圾收集,但是您所指的字典不会被收集,因为您仍在使用它。您可以在该类上放置一个析构函数并调用 GC.Collect() 以查看是否要调用析构函数。

标签: c# .net garbage-collection reference


【解决方案1】:

但这是否意味着 emptyBook 将引用 oldBook,因此 oldBook 不能再被垃圾收集?

不,除非你没有提到其他事情。

这里只有两个对象(emptyBookoldbook引用同一个 Books 字典。这不会在它们之间创建任何引用关系;每个人都无法知道对方。

只要 oldbook 不能通过另一个引用从 root 访问,它就有资格进行垃圾回收。

【讨论】:

    【解决方案2】:

    如果没有从您的字典直接或间接引用回您的视图模型类,那么就没有问题。

    emptyBook 和 oldBook 只会引用同一个字典,但传出引用不会停止垃圾收集,只有传入连接会这样做。

    【讨论】:

      【解决方案3】:

      此外,我想说的是,考虑到TabControl 的“美”,用户可以始终只使用一个标签。考虑有一个View Model,后面有多个Models。基于Tab 选择总是相同的View Model 从模型的集合中挑选正确的Tradebook。在Tab selection changed 上,View Model 被分配给一个活动选项卡。

      【讨论】:

        【解决方案4】:

        Book 和本书指向的字典是两个独立的对象。一个只是指另一个。

        引用类的字段或属性不会创建对包含该字段或属性的类的引用。

        如果您存储对oldbook.DisplayName 的引用,则您存储的是对字典对象的引用。您没有存储对oldbook 指向的Book 对象的引用。

        当垃圾收集器运行时,它会看到您正在引用字典,并且不会收集它。它会发现您没有引用Book,并会收集它。

        这当然假设您实际上并没有在其他任何地方引用Book 对象。如果没有类具有 oldbook 引用的对象作为属性或字段,并且您已将其从任何容器中删除,或者不再引用包含 Book 的容器,那么它将被收集。

        【讨论】:

          猜你喜欢
          • 2017-12-05
          • 2020-01-29
          • 1970-01-01
          • 2013-04-04
          • 1970-01-01
          • 2023-03-11
          • 2012-01-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多