2010-04-20 30 views
12

Tôi có một đối tượng, mà tôi tin rằng chỉ được tổ chức bởi một WeakReference. Tôi đã theo dõi các tài liệu tham khảo của nó bằng cách sử dụng SOS và SOSEX, và cả hai xác nhận rằng đây là trường hợp (Tôi không phải là một chuyên gia SOS, vì vậy tôi có thể sai về điểm này).Làm cách nào để Garbage Collector quyết định khi nào nên giết các đối tượng do WeakReferences tổ chức?

Giải thích chuẩn của WeakReferences là GC bỏ qua chúng khi thực hiện quét. Tuy nhiên, đối tượng của tôi tồn tại một lời gọi đến GC.Collect (GC.MaxGeneration, GCCollectionMode.Forced).

Có thể cho một đối tượng chỉ được tham chiếu với một WeakReference để tồn tại bộ sưu tập đó không? Có một bộ sưu tập kỹ lưỡng hơn mà tôi có thể ép buộc không? Hoặc, tôi có nên thăm lại niềm tin của mình rằng chỉ những tham chiếu đến đối tượng là yếu?

Update và Kết luận

Các nguyên nhân gốc rễ là có một tài liệu tham khảo trên stack đã được khóa đối tượng. Đó là chưa rõ tại sao SOS và SOSEX cũng không cho thấy tham chiếu đó. Lỗi người dùng luôn là một khả năng.

Trong quá trình chẩn đoán nguyên nhân gốc rễ, tôi đã thực hiện một số thí nghiệm đã chứng minh rằng WeakReferences cho các đối tượng thế hệ thứ 2 có thể dính quanh một thời gian dài đáng ngạc nhiên. Tuy nhiên, đối tượng gen WRd thứ 2 sẽ không tồn tại GC.Collect (GC.MaxGeneration, GCCollectionMode.Forced).

+0

Đối tượng _aren't_ được tổ chức bởi WeakReferences. Đó chính là điểm của họ. Có thể có thứ gì đó khác đang giữ họ sống. – zneak

+0

Điều gì xảy ra khi bạn gọi GC.GetGeneration (yourWeakReference)?Liệu nó trả lại một cái gì đó hoặc ném một ngoại lệ? – MusiGenesis

+0

Điều gì xảy ra! Gchandles và! Gcroot hiển thị? –

Trả lời

0

Theo wikipedia "Một đối tượng tham chiếu chỉ bởi tài liệu tham khảo yếu được coi là không thể truy cập (hoặc 'một cách yếu ớt có thể truy cập') và như vậy có thể được thu thập bất cứ lúc nào. Tài liệu tham khảo yếu được sử dụng để tránh giữ bộ nhớ tham chiếu bởi các đối tượng không cần thiết"

Tôi không chắc liệu trường hợp của bạn có phải là tài liệu tham khảo yếu hay không ...

+1

Tôi biết rõ mô tả chuẩn về các tham chiếu yếu. Trường hợp của tôi là xem xét lại mô tả chuẩn về các tham chiếu yếu vì tôi hiện đang phải đối mặt với bằng chứng cho thấy rằng hành vi thực tế phức tạp hơn. –

0

Hãy thử gọi GC.WaitForPendingFinalizers() ngay sau GC.Collect().

Một tùy chọn có thể khác: không bao giờ sử dụng WeakReference cho bất kỳ mục đích nào. Trong tự nhiên, tôi đã từng thấy chúng được sử dụng như một cơ chế để giảm dấu chân bộ nhớ của ứng dụng (tức là một dạng bộ nhớ đệm). Khi hùng mạnh MSDN nói:

Tránh sử dụng tài liệu tham khảo yếu như một giải pháp tự động đến vấn đề quản lý bộ nhớ . Thay vào đó, hãy phát triển chính sách lưu bộ nhớ cache hiệu quả để xử lý các đối tượng của ứng dụng của bạn.

+0

Tôi có WaitForPendingFinalizers trong mã của mình. Tôi thường đồng ý với bạn rằng 99% thời gian nếu bạn đang sử dụng WR, bạn đang làm sai. Tôi nghĩ đây là trường hợp 1%. Tôi phải giữ một danh sách trung tâm của các đối tượng mà không ảnh hưởng đến tuổi thọ đối tượng. –

+0

Hầu hết thời gian, khi 'Foo' giữ một tham chiếu đến' Bar', nó sẽ làm như vậy bởi vì nó "cần" 'Bar'. Tuy nhiên, trong một số trường hợp, 'Foo' có thể giữ một tham chiếu đến' Bar' hoàn toàn để nó có thể làm mọi thứ * vì lợi ích của các đối tượng khác cần 'Bar' *. Nếu không có bất kỳ đối tượng nào cần thanh, 'Foo' sẽ sớm có' Bar', và tham chiếu đến nó, thay thế bằng một dấu hiệu cho thấy nó không còn cần phục vụ nó nữa. – supercat

+0

@supercat trong trường hợp thứ hai của bạn, điều cần sử dụng trong .NET 4+ không phải là WeakReference, nhưng [ConditionalWeakTable] (http://msdn.microsoft.com/en-us/library/dd287757.aspx). –

0

Tôi khuyên bạn nên kiểm tra các tham chiếu "khác" với các đối tượng được tham chiếu yếu. Bởi vì, nếu có một tham chiếu khác vẫn còn sống, các đối tượng sẽ không được GC.

+1

Điều này đã được đề cập. –

0

Đối tượng yếu được tham chiếu do bị xóa bằng cách thu thập rác. Tôi đã có niềm vui của việc gỡ lỗi các hệ thống sự kiện mà các sự kiện không bị sa thải ... Nó xuất hiện là do người đăng ký chỉ tham chiếu yếu và do đó sau một số trễ ngẫu nhiên cuối cùng, GC cuối cùng sẽ thu thập nó. Tại thời điểm đó giao diện người dùng ngừng cập nhật. :)

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