NÀY NÊN LÀ BẤT HỢP VỚI JAVA 9!
Sử dụng java.util.Cleaner
để thay thế! (Hoặc sun.misc.Cleaner
trên JRE cũ)
Original post:
tôi thấy rằng việc sử dụng các PhantomReferences có gần cùng một lượng cạm bẫy như các phương pháp finalizer (nhưng một ít vấn đề hơn khi bạn làm cho nó đúng). Tôi đã viết một giải pháp nhỏ (một khung công tác rất nhỏ để sử dụng PhantomReferences) cho Java 8. Nó cho phép sử dụng các biểu thức lambda như các cuộc gọi lại để chạy sau khi đối tượng đã được gỡ bỏ. Bạn có thể đăng ký cuộc gọi lại cho các tài nguyên bên trong cần được đóng lại. Với điều này tôi đã tìm thấy một giải pháp phù hợp với tôi vì nó làm cho nó thực tế hơn nhiều.
https://github.com/claudemartin/java-cleanup
Dưới đây là một ví dụ nhỏ để chứng tỏ một callback được đăng ký:
class Foo implements Cleanup {
//...
public Foo() {
//...
this.registerCleanup((value) -> {
try {
// 'value' is 'this.resource'
value.close();
} catch (Exception e) {
logger.warning("closing resource failed", e);
}
}, this.resource);
}
Và sau đó là phương pháp đơn giản hơn để tự động đóng, làm về giống như trên:
this.registerAutoClose(this.resource);
Để trả lời câu hỏi của bạn:
[sau đó sử dụng nó]
Bạn không thể dọn sạch thứ gì đó không tồn tại. Nhưng nó có thể có nguồn tài nguyên vẫn tồn tại và cần phải được làm sạch để chúng có thể được loại bỏ.
Nhưng việc sử dụng khái niệm/lớp học này là gì?
Không nhất thiết phải làm bất cứ điều gì với bất kỳ hiệu ứng nào khác ngoài gỡ lỗi/ghi nhật ký. Hoặc có thể cho thống kê. Tôi thấy nó giống như một dịch vụ thông báo từ GC. Bạn cũng có thể muốn sử dụng nó để xóa dữ liệu tổng hợp không liên quan khi đối tượng bị xóa (nhưng có thể có giải pháp tốt hơn cho điều đó). Ví dụ thường đề cập đến các kết nối cơ sở dữ liệu bị đóng, nhưng tôi không thấy đây là một ý tưởng hay như bạn không thể làm việc với các giao dịch. Một khung ứng dụng sẽ cung cấp một giải pháp tốt hơn cho điều đó.
Bạn đã bao giờ sử dụng điều này trong bất kỳ dự án nào của mình hay bạn có ví dụ nào về việc chúng tôi nên sử dụng điều này không? Hoặc là khái niệm này chỉ được thực hiện cho điểm phỏng vấn;)
Tôi sử dụng chủ yếu chỉ để ghi nhật ký. Vì vậy, tôi có thể theo dõi các yếu tố đã xóa và xem cách GC hoạt động và có thể được tinh chỉnh. Tôi sẽ không chạy bất kỳ mã quan trọng theo cách này. Nếu một cái gì đó cần phải được đóng lại thì nó nên được thực hiện trong một tuyên bố try-with-resource. Và tôi sử dụng nó trong các bài kiểm tra đơn vị, để đảm bảo rằng tôi không có bất kỳ rò rỉ bộ nhớ nào. Cách tương tự như jontejj làm điều đó. Nhưng giải pháp của tôi là tổng quát hơn một chút.
Cũng https://stackoverflow.com/a/9827686/632951 – Pacerier
Vì bạn không thể lấy obj được giới thiệu của PhantomReference, một từ sai hoàn toàn của nó: Nó phải được gọi là 'FakeReference' hoặc' NonReference'. – Pacerier
Đây là chuỗi anothre có mã: https://stackoverflow.com/q/43311825/632951 – Pacerier