[英]C# reference object still alive after GC.Collect
在語句中var list = Foo();
CLR執行Library = null;
在GC.Collect(2)
行上進入調試模式后; 列表仍然有10個元素。 為什么不將其設置為null? 它針對哪個對象執行Library = null;
?
public class Book
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Controller : IDisposable
{
public List<Book> Library = null;
public Controller()
{
Console.WriteLine("Controller created.");
Console.WriteLine("List created.");
Library = new List<Book>();
for (int i = 0; i < 10; i++)
{
Library.Add(new Book { FirstName = "FirstName" + i.ToString(), LastName = "LastName" + i.ToString() });
}
}
public void Dispose()
{
Library = null; // Just for check
Console.WriteLine("List disposed.");
}
}
class Program
{
private static List<Book> Foo()
{
using (var lib = new Controller())
{
return lib.Library;
}
}
static void Main(string[] args)
{
var list = Foo();
GC.Collect(0);
GC.Collect(1);
GC.Collect(2);
}
}
Foo()
返回對在Controller
創建的書籍列表的引用,並且該引用存儲在變量list
。 垃圾收集器不會收集書籍列表,因為程序仍在引用該列表。 如果沒有包含對書的引用的變量,則該書列表將被垃圾回收。
如果在不存儲返回值的情況下調用Foo()
,則書籍列表將被標記為垃圾收集,並且在垃圾收集器運行時最終將被收集。
“它對哪個對象執行
Library = null;
?”
Dispose
是在結束時自動調用using
塊,所以這個代碼是其中Library
被設置為null
:
private static List<Book> Foo()
{
using (var lib = new Controller())
{
return lib.Library;
} // <-- Dispose is called here on 'lib'
}
請注意,這是在獲得對Library
的return
語句的引用之后調用的,因此該方法仍然返回有效的引用。
並且因為返回了對列表的引用(而不是null引用),所以這就是list
不是null
。
如果在獲取引用之前有意調用Dispose
,則Library
將為null
:
private static List<Book> Foo()
{
using (var lib = new Controller())
{
lib.Dispose();
return lib.Library; // Now 'Library' is null
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.