2009-08-04 38 views
5

Tôi chỉ đào bới xung quanh trong thư viện commons-io và thấy điều này:Chờ cho Garbage Collection của một đối tượng cụ thể

 
Keeps track of files awaiting deletion, and deletes them when 
an associated marker object is reclaimed by the garbage collector. 

này có thể được tìm thấy trong các tài liệu hướng dẫn cho các đối tượng FileCleaningTracker.

Bây giờ tôi chỉ tò mò làm thế nào tôi có thể làm điều này một mình? Làm thế nào mã của tôi có thể phát hiện khi một đối tượng được khai hoang bởi bộ thu gom rác?

Trả lời

9

Theo the source code, nó sử dụng lớp PhantomReference. Theo tài liệu:

Đối tượng tham chiếu Phantom được liệt kê sau khi người thu thập xác định rằng các tham chiếu của họ có thể bị thu hồi. Tài liệu tham khảo Phantom thường được sử dụng để lên lịch cho các hành động dọn dẹp trước khi xử lý một cách linh hoạt hơn khả năng với cơ chế hoàn thiện Java.

Nếu bộ thu gom rác xác định tại một thời điểm nhất định thì tham chiếu của tham chiếu ảo có thể truy cập được, sau đó tại thời điểm đó hoặc vào một thời gian sau nó sẽ đưa ra tham chiếu.

Để đảm bảo rằng đối tượng có thể khôi phục vẫn như vậy, tham chiếu của tham chiếu ảo có thể không được truy xuất: Phương thức get của tham chiếu ảo luôn trả về giá trị rỗng.

Không giống như tài liệu tham khảo mềm và yếu, tham chiếu ảo không tự động xóa bởi bộ thu gom rác khi chúng được đặt hàng. Một đối tượng có thể truy cập thông qua các tham chiếu ảo sẽ vẫn như vậy cho đến khi tất cả các tham chiếu như vậy bị xóa hoặc bản thân chúng trở nên không thể truy cập được.

Các constructor PhantomReference chấp nhận hai đối số:

referent - đối tượng tham chiếu phantom mới sẽ tham khảo

q - hàng đợi mà tham chiếu là được đăng ký, hoặc null nếu không cần đăng ký

Đối số q là một bản sao ance của lớp ReferenceQueue. Các PhantomReference sẽ được thêm vào này ReferenceQueue khi nó là referent trở thành ma có thể truy cập. Khi điều này xảy ra, bạn có thể truy xuất PhantomReference bằng cách sử dụng các phương pháp poll() hoặc remove() của lớp ReferenceQueue.

Ví dụ:

T objectToWatch = ...; 
ReferenceQueue<T> referenceQueue = new ReferenceQueue<T>(); 
new PhantomReference<T>(objectToWatch, referenceQueue); 

// Later on, probably in another thread... 
Reference<? extends T> nextReference = referenceQueue.remove(); 
// Tidy up! 

Lưu ý: PhantomReference có các lớp anh chị em ruột có tên là SoftReferenceWeakReference mà cũng có thể sử dụng. Mối quan hệ giữa các tài liệu này được ghi lại trong số java.lang.ref package documentation.

1

Không chắc chắn nếu điều này thực sự trả lời câu hỏi của bạn, nhưng phương thức finalize() của một đối tượng được gọi trước khi tài nguyên của nó được khai hoang.

Chỉnh sửa: Điều đó có nghĩa là bạn có thể gửi tin nhắn tới một đối tượng khác để cảnh báo hoặc một thứ gì đó dọc theo các dòng đó.

+4

Không sử dụng finalizers cho mục đích này, hoặc bất kỳ khác nếu bạn có thể tránh nó. Không có gì đảm bảo rằng phương thức finalize() sẽ được gọi ngay sau khi thu gom rác, hoặc thậm chí nó sẽ được gọi ở tất cả (Xem Hiệu quả Java 2nd Ed, Mục 7). Gói java.lang.ref là cách để đi. – Leigh

+0

Nếu bạn có thể giúp, đừng sử dụng finalizers! http://stackoverflow.com/a/158791/74694 –

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