2015-02-12 11 views
8

Vì vậy, tôi có điều này chỉ đơn giản là Chuông lớp mà tôi đang thử nghiệm thu gom rác thải trên:Bộ sưu tập rác - Một công trình nhưng không phải là công trình khác, làm thế nào đến?

public class Bell 
{ 
    public void Ring() 
    { 
     Console.WriteLine("Ding ding"); 
    } 
} 

Nếu tôi chạy đoạn mã này dưới đây, nó không được thu gom rác thải

class Program 
{ 
    private static WeakReference reference; 

    private static void Main() 
    { 
     Console.WriteLine("Starting"); 

     var bell = new Bell(); 
     reference = new WeakReference(bell); 
     bell = null; 

     GC.Collect(); 

     Console.WriteLine("Object still alive: {0}", reference.IsAlive); 

     if (reference.Target == null) 
     { 
      Console.WriteLine("Bell is no more!"); 
     } 
     else 
     { 
      { 
       var theBell = (Bell)reference.Target; 
       theBell.Ring(); 
      } 
     } 

     Console.ReadLine(); 
    } 
} 

Nếu tôi tuy nhiên chỉ kiểm tra reference.IsAlive như dưới đây, rác của nó được thu thập

class Program 
{ 
    private static WeakReference reference; 

    private static void Main() 
    { 
     Console.WriteLine("Starting"); 

     var bell = new Bell(); 
     reference = new WeakReference(bell); 
     bell = null; 

     GC.Collect(); 

     Console.WriteLine("Object still alive: {0}", reference.IsAlive); 

     Console.ReadLine(); 
    } 
} 

Các bạn có thể giải thích cho tôi cách hoạt động này không?

+1

Nó hoạt động tương tự với tôi trong LINQPad, nhưng khi tôi thử nó trong VS 2013, nó luôn được thu thập - gỡ lỗi/phát hành, .NET 3.5, 4.0, 4.5, 4.5.1 – Ondra

Trả lời

2

Đó là bởi vì các loại đối tượng của bạn của reference (source)

Đại diện cho một tài liệu tham khảo yếu, có sự tham khảo một đối tượng trong khi vẫn cho phép đối tượng đó được khai hoang bởi thu gom rác thải.

Và sau đây có thể có thể giải thích tại sao hai kịch bản hành xử khác nhau (Source)

Tham chiếu yếu cho phép thu gom rác để thu thập các đối tượng trong khi vẫn cho phép các ứng dụng để truy cập vào các đối tượng. Tham chiếu yếu chỉ hợp lệ trong khoảng thời gian không xác định cho đến khi đối tượng được thu thập khi không có tham chiếu mạnh nào tồn tại. Khi bạn sử dụng một tham chiếu yếu, ứng dụng vẫn có thể có được một tham chiếu mạnh mẽ đến đối tượng, ngăn cản nó được thu thập. Tuy nhiên, luôn luôn có nguy cơ mà người thu gom rác sẽ tới đối tượng trước khi một tham chiếu mạnh được tái lập.

Sau nhiều lần chạy [Với một số trường hợp thử nghiệm]: Theo tôi

Các if-else là chìa khóa tôi nghĩ. Sau Writeline, đối tượng được tham chiếu lại cho phép để có được một tham chiếu mạnh mẽ trước khi GC làm sạch đối tượng.

Một lần nữa cụm từ này là chìa khóa

Tuy nhiên, luôn luôn có rủi ro mà các nhà sưu tập rác sẽ đến được với các đối tượng đầu tiên trước một tài liệu tham khảo mạnh mẽ được tái lập.

+2

Nhưng điều đó cũng giống nhau trong cả hai trường hợp hỏi về ... –

+0

@Justin Harvey - đúng. .i thà giữ lời giải thích này hơn là câu trả lời đúng .. –

+1

Đọc lại bây giờ bạn đã mở rộng một chút, tôi có khuynh hướng đồng ý, trong khi đó không hoàn toàn là câu trả lời đầy đủ cho câu hỏi, đó là thông tin hữu ích và giúp giải thích câu trả lời đầy đủ. –

6

Bạn đang cố thử nghiệm với chế độ gỡ lỗi. GC không tích cực trong chế độ gỡ lỗi vì nó hoạt động trong chế độ phát hành (với công tắc tối ưu được bật). Điều này làm cho gỡ lỗi dễ dàng, nếu không bạn sẽ tìm thấy những điều kỳ lạ trong khi gỡ lỗi. Ví dụ: Bạn có thể thử kiểm tra giá trị của biến đã thu thập rác.

Chạy mã ở chế độ phát hành và bạn có thể thấy Bell sẽ là GC'd.

+0

Tôi có thể xác minh điều này vừa thử. –

+0

Điều này có ý nghĩa, tuy nhiên hãy xem nhận xét của tôi cho câu hỏi. Nó luôn được thu thập trong trường hợp của tôi, vì vậy phải có nhiều quy tắc hơn. – Ondra

Các vấn đề liên quan