此引用是否会导致内存泄漏?

时间:2011-12-06 09:44:22

标签: c# .net garbage-collection reference

我有一个TabControl,每个标签都包含一个TradeBookSetViewModel。由于Tradebook可以变得非常大,用户可以根据需要删除该书。

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

_bookSetViewModels.Remove(oldbook);

然后我创建一个新的emptyBook作为占位符并将其插入相同的选项卡位置。 Tab仍然看起来像握着tradeBook,但它实际上是空的。

为此,我从Unity容器中解析出一个新实例,并将DisplayBook从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;

但这不是说空书会引用旧书,因此旧书不能再被垃圾收集了吗?

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

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

目标:在一天结束时,我需要将emptyBook中的Books属性设置为null,然后oldBook才能被垃圾回收。有什么想法吗?

4 个答案:

答案 0 :(得分:1)

  

但这不是说空书会引用旧书,因此旧书不能再被垃圾收集了吗?

不,除非你还没有提到别的东西。

这里只有两个对象(emptyBookoldbook),引用相同的Books字典。这并没有在它们之间建立任何参考关系;每个人都无法了解对方。

只要{root>无法通过其他引用访问oldbook,它就有资格进行垃圾回收。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

另外,我会考虑TabControl的“美”,该用户可以始终只使用一个Tab 。考虑让一个View Model,后面有多个Models。根据所选的Tab始终使用与模型集合相同的View Model选项正确Tradebook。在Tab selection changed上,View Model被分配到有效标签。

答案 3 :(得分:0)

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

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

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

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

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