Cập nhật (ngày 1 tháng 12 năm 2009):
Tôi muốn sửa đổi câu trả lời này và thừa nhận rằng câu trả lời ban đầu là thiếu sót.
Các phân tích ban đầu không áp dụng đối với các đối tượng yêu cầu kết thúc - và thời điểm đó thực hành không nên được chấp nhận trên bề mặt mà không có một chính xác, sâu sự hiểu biết vẫn đứng.
Tuy nhiên, hóa ra DataSets, DataViews, DataTables ngăn chặn quyết toán trong các hàm tạo của chúng - đây là lý do tại sao việc gọi Dispose () trên chúng rõ ràng không làm gì cả.
Có lẽ, điều này xảy ra bởi vì họ không có tài nguyên không được quản lý; Vì vậy, mặc dù thực tế là MarshalByValueComponent tạo ra các khoản phụ cấp cho các tài nguyên không được quản lý, những triển khai cụ thể này không có nhu cầu và do đó có thể từ bỏ quyết toán.
(Các tác giả .NET đó sẽ quan tâm đến việc triệt tiêu quyết toán đối với chính các loại thường chiếm nhiều bộ nhớ nhất nói lên tầm quan trọng của thực tiễn này nói chung đối với các loại hoàn thiện.)
Mặc dù vậy, các chi tiết này vẫn chưa được ghi chép đầy đủ kể từ khi .NET Framework ra đời (gần 8 năm trước) khá đáng ngạc nhiên (về cơ bản bạn để các thiết bị của mình để sàng lọc mặc dù các vật liệu mơ hồ, mâu thuẫn để đặt các mảnh ghép lại với nhau đôi khi làm nản lòng nhưng không cung cấp sự hiểu biết đầy đủ hơn về khuôn khổ mà chúng ta dựa vào hàng ngày).
Sau khi đọc rất nhiều, đây là sự hiểu biết của tôi:
Nếu một đối tượng yêu cầu hoàn thiện, nó có thể chiếm bộ nhớ lâu hơn mức cần thiết - đây là lý do: a) Bất kỳ loại nào xác định hàm hủy (hoặc kế thừa từ một loại xác định hàm hủy) đều được coi là hoàn thiện; b) Khi cấp phát (trước khi hàm tạo chạy), một con trỏ được đặt trên hàng đợi Hoàn thiện; c) Một đối tượng có thể hoàn thiện thường yêu cầu thu hồi 2 bộ sưu tập (thay vì tiêu chuẩn 1); d) Việc loại bỏ quyết toán không loại bỏ một đối tượng khỏi hàng đợi quyết toán (như được báo cáo bởi! FinalizeQueue trong SOS) Lệnh này gây hiểu nhầm; Biết những đối tượng nào trong hàng đợi quyết toán (trong và chính nó) không hữu ích; Biết những đối tượng nào trong hàng đợi quyết toán và vẫn yêu cầu hoàn thiện sẽ hữu ích (có lệnh nào cho việc này không?)
Việc loại bỏ hoàn thiện sẽ tắt một chút trong tiêu đề của đối tượng cho biết thời gian chạy rằng nó không cần phải có Trình hoàn thiện của nó được gọi (không cần phải di chuyển hàng đợi FReachable); Nó vẫn còn trên hàng đợi Quyết toán (và tiếp tục được báo cáo bởi! FinalizeQueue trong SOS)
Các lớp DataTable, Dataset, DataView đều được bắt nguồn từ MarshalByValueComponent, một đối tượng hoàn thiện có thể (có khả năng) xử lý các tài nguyên không được quản lý
- Vì DataTable, Dataset, DataView không giới thiệu các tài nguyên không được quản lý, chúng ngăn chặn việc hoàn thiện trong các hàm tạo của chúng
- Mặc dù đây là một mẫu không bình thường, nhưng nó giúp người gọi không phải lo lắng về việc gọi Vứt bỏ sau khi sử dụng
- Điều này và thực tế là DataTables có thể có khả năng được chia sẻ trên các DataSets khác nhau, có khả năng là lý do tại sao DataSets không quan tâm đến việc xử lý DataTables con
- Điều này cũng có nghĩa là các đối tượng này sẽ xuất hiện dưới! FinalizeQueue trong SOS
- Tuy nhiên, những đối tượng này vẫn có thể được thu hồi sau một bộ sưu tập duy nhất, như các đối tác không thể hoàn thiện của chúng
4 (tài liệu tham khảo mới):
Câu trả lời gốc:
Có rất nhiều câu trả lời sai lệch và nói chung rất kém về điều này - bất kỳ ai hạ cánh ở đây nên bỏ qua tiếng ồn và đọc các tài liệu tham khảo dưới đây một cách cẩn thận.
Không còn nghi ngờ gì nữa, Vứt bỏ nên được gọi trên bất kỳ đối tượng Hoàn thiện nào.
DataTables có thể hoàn thành .
Gọi Vứt bỏ đáng kể tăng tốc độ lấy lại bộ nhớ.
MarshalByValueComponent gọi GC.SuppressFinalize (this) trong Dispose () - bỏ qua điều này có nghĩa là phải chờ hàng chục nếu không phải hàng trăm bộ sưu tập Gen0 trước khi bộ nhớ được lấy lại:
Với sự hiểu biết cơ bản về hoàn thiện này, chúng ta đã có thể suy ra một số điều rất quan trọng:
Đầu tiên, các đối tượng cần hoàn thiện sẽ sống lâu hơn các đối tượng không. Trên thực tế, họ có thể sống lâu hơn rất nhiều. Chẳng hạn, giả sử một đối tượng nằm trong gen2 cần được hoàn thiện. Hoàn thiện sẽ được lên lịch nhưng đối tượng vẫn ở gen2, vì vậy nó sẽ không được thu thập lại cho đến khi bộ sưu tập gen2 tiếp theo xảy ra. Đó thực sự có thể là một thời gian rất dài, và trên thực tế, nếu mọi thứ đang diễn ra tốt đẹp thì đó sẽ là một thời gian dài, bởi vì các bộ sưu tập gen2 rất tốn kém và do đó chúng tôi muốn chúng xảy ra rất ít khi xảy ra. Các đối tượng cũ hơn cần hoàn thiện có thể phải chờ hàng chục nếu không phải là hàng trăm bộ sưu tập gen0 trước khi không gian của chúng được lấy lại.
Thứ hai, các đối tượng cần hoàn thiện gây ra thiệt hại tài sản thế chấp. Do các con trỏ đối tượng bên trong phải còn hiệu lực, nên không chỉ các đối tượng cần trực tiếp hoàn thiện sẽ lưu lại trong bộ nhớ mà tất cả mọi thứ mà đối tượng đề cập, trực tiếp và gián tiếp, cũng sẽ vẫn còn trong bộ nhớ. Nếu một cây khổng lồ của các vật thể được neo bởi một vật thể cần phải hoàn thiện, thì toàn bộ cây sẽ tồn tại, có khả năng trong một thời gian dài như chúng ta vừa thảo luận. Do đó, điều quan trọng là sử dụng các công cụ hoàn thiện một cách tiết kiệm và đặt chúng trên các đối tượng có càng ít con trỏ đối tượng bên trong càng tốt. Trong ví dụ về cây tôi vừa đưa ra, bạn có thể dễ dàng tránh được vấn đề bằng cách di chuyển các tài nguyên cần hoàn thiện sang một đối tượng riêng biệt và giữ một tham chiếu đến đối tượng đó trong thư mục gốc của cây.
Cuối cùng, các đối tượng cần hoàn thiện tạo công việc cho luồng hoàn thiện. Nếu quá trình hoàn thiện của bạn là một quá trình phức tạp, thì chuỗi xử lý một và duy nhất sẽ dành nhiều thời gian để thực hiện các bước đó, điều này có thể gây ra tồn đọng công việc và do đó khiến nhiều đối tượng phải nán lại chờ đợi quyết toán. Do đó, điều cực kỳ quan trọng là người hoàn thiện làm càng ít việc càng tốt. Cũng cần nhớ rằng mặc dù tất cả các con trỏ đối tượng vẫn còn hiệu lực trong quá trình hoàn thiện, nhưng có thể xảy ra trường hợp các con trỏ đó dẫn đến các đối tượng đã được hoàn thiện và do đó có thể ít hữu ích hơn. Nói chung là an toàn nhất để tránh theo dõi các con trỏ đối tượng trong mã quyết toán mặc dù các con trỏ là hợp lệ. Một đường dẫn mã quyết toán an toàn, ngắn là tốt nhất.
Lấy nó từ một người đã xem 100 MB MB DataTables không được tham chiếu trong Gen2: điều này cực kỳ quan trọng và hoàn toàn bị bỏ lỡ bởi các câu trả lời trên chuỗi này.
Người giới thiệu:
1 -
http://msdn.microsoft.com/en-us/l Library / ms973837.aspx
2 -
http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry
http://www.dotnetfunda.com/articles/article524-net-best-practice-no-2-improve-garbage -collector-Performance-using-Finalizedispose-pattern.aspx
3 -
http://codeidol.com/csharp/net-framework/Inside-the-CLR/Automatic-Memory-Quản lý /