这个引用会导致内存泄漏吗?

本文关键字:内存 泄漏 引用 | 更新日期: 2023-09-27 18:16:58

我有一个TabControl,每个tab包含一个TradeBookSetViewModel。由于Tradebook可以变得相当大,如果需要,用户可以删除这本书。

对于DeleteBook(),我只是从observablecollection中删除TradeBookSetViewModel:

_bookSetViewModels.Remove(oldbook);

然后创建一个新的emptyBook作为占位符,并将其插入到相同的制表符位置。选项卡看起来仍然是持有tradeBook,但它实际上是空的。

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

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

一切顺利。

但是后来我意识到emptyBook也需要Books属性。属性Books的类型是Dictionary<string, CustomClassItem>,因此我认为首先我可以做同样的事情,因为我做了与DisplayName。

emptyBook.Books = oldbook.Books;

但这是否意味着空book将指向oldBook,因此oldBook不能再被垃圾收集了呢?

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

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

目标:在一天结束时,我需要在emptyBook中的Books属性不为空,但oldBook应该能够被垃圾收集。任何想法吗?

这个引用会导致内存泄漏吗?

但这是否意味着空book将指向oldBook,因此oldBook不能再被垃圾收集了呢?

不,除非你还有别的事情没有提到。

这里所有的是两个对象(emptyBookoldbook), 引用相同的Books字典。这不会在它们之间产生任何引用关系;每个人都无法知道对方的情况。

只要oldbook不能通过其他引用从根访问,它就有资格进行垃圾收集。

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

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

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

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

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

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

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

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