Tìm kiếm rất nhiều về tham chiếu ma nhưng không thể tìm thấy cách sử dụng thực tế của nó. Và một cách logic các get() phương pháp trả về null trong trường hợp của Tài liệu tham khảo PhantomViệc sử dụng thực tế các tham chiếu ảo - JAVA là gì?
Trả lời
Bạn có thể làm theo này blog:
tốt là gì PhantomReferences? Tôi chỉ biết hai trường hợp nghiêm trọng đối với họ: đầu tiên, chúng cho phép bạn xác định chính xác khi một đối tượng bị xóa khỏi bộ nhớ. Trên thực tế, đó là cách duy nhất để xác định điều đó. Điều này thường không hữu ích, nhưng có thể có ích trong các trường hợp cụ thể như thao tác hình ảnh lớn: nếu bạn biết chắc chắn rằng một hình ảnh phải được thu gom rác, bạn có thể đợi cho đến khi nó thực sự trước khi cố gắng tải hình ảnh tiếp theo, và do đó làm cho OutOfMemoryError sợ hãi ít có khả năng xảy ra.
Thứ hai, PhantomReferences tránh một vấn đề cơ bản với hoàn thiện: phương thức finalize() có thể "hồi sinh" các đối tượng bằng cách tạo các tham chiếu mới mạnh mẽ cho chúng. Vì vậy, những gì, bạn nói? Vâng, vấn đề là rằng một đối tượng ghi đè hoàn chỉnh() bây giờ phải được xác định là rác trong ít nhất hai chu kỳ thu gom rác riêng biệt để thu thập . Khi chu kỳ đầu tiên xác định rằng đó là rác, nó trở nên đủ điều kiện để hoàn thành. Bởi vì khả năng (mỏng, nhưng không may thực) mà đối tượng đã "phục sinh" trong quá trình hoàn thiện, trình thu gom rác phải chạy lại trước khi đối tượng thực sự có thể bị xóa. Và bởi vì hoàn thành có thể không đã xảy ra một cách kịp thời, một số lượng tùy ý của rác chu kỳ thu thập có thể đã xảy ra trong khi đối tượng đang chờ kết quả thanh toán . Điều này có thể có nghĩa là sự chậm trễ nghiêm trọng trong thực tế làm sạch các đối tượng rác , và là lý do tại sao bạn có thể nhận được OutOfMemoryErrors ngay cả khi hầu hết các đống rác.
Cũng đọc: The Mysterious Phantom Reference
Xét đoạn mã sau.
public class Foo { private String bar; public Foo(String bar) { this.bar = bar; } public String foo() { return bar; } }
Vì vậy, cho phép nói sau khi đối tượng đã được hoàn toàn dereferenced bởi ứng dụng Tôi muốn một số cách gọi foo(). Đây là một số mã mà tôi dự kiến sẽ hoạt động mà sẽ làm điều này với một niggle.
// initialize ReferenceQueue<Foo> queue = new ReferenceQueue<Foo>(); ArrayList< PhantomReference<Foo>> list=new ArrayList<PhantomReference<Foo>>(); for (int i = 0; i < 10; i++) { Foo o = new Foo(Integer.toOctalString(i)); list.add(new PhantomReference<Foo>(o, queue)); } // make sure the garbage collector does it’s magic System.gc(); // lets see what we’ve got Reference<? extends Foo> referenceFromQueue; for (PhantomReference<Foo> reference : list) System.out.println(reference.isEnqueued()); while ((referenceFromQueue = queue.poll()) != null) { System.out.println(referenceFromQueue.get()); referenceFromQueue.clear(); }
PhantomReference có phiên bản Foo và ReferenceQueue. Kể từ không có tay cầm nào được giữ cho Foo, nó sẽ ngay lập tức bị chết. Tiếp theo, yêu cầu máy ảo thu thập vì không đủ số lượng để máy ảo kích hoạt bộ sưu tập một cách tự nhiên. Điều đầu tiên tôi sẽ yêu cầu PhantomReference là; bạn đã được enqueued. Trong trường hợp này, câu trả lời sẽ là đúng. Tiếp theo, tôi yêu cầu hàng đợi tham chiếu nhưng khi bạn có thể thấy, gọi get() luôn trả về giá trị rỗng. Về giải pháp duy nhất mà có ý nghĩa là bao bọc các tài nguyên hoặc đối tượng bạn muốn tương tác với trong một phân lớp của PhantomReference.
public class FinalizeStuff<Foo> extends PhantomReference<Foo> { public FinalizeStuff(Foo foo, ReferenceQueue<? super Foo> queue) { super(foo, queue); } public void bar() { System.out.println("foobar is finalizing resources"); } }
Trong trường hợp này tôi sẽ không để quấn Foo trong lớp con như rằng sẽ dường như vi phạm tinh thần của PhantomReference. Thay vào đó, tôi sẽ truy cập vào tài nguyên được liên kết với Foo và tương tác với chúng. Bây giờ tôi có thể làm điều này.
// initialize ReferenceQueue<Foo> queue = new ReferenceQueue<Foo>(); ArrayList< FinalizeStuff<Foo>> list = new ArrayList<FinalizeStuff<Foo>>(); ArrayList<Foo> foobar = new ArrayList<Foo>(); for (int i = 0; i < 10; i++) { Foo o = new Foo(Integer.toOctalString(i)); foobar.add(o); list.add(new FinalizeStuff<Foo>(o, queue)); } // release all references to Foo and make sure the garbage collector does it’s magic foobar = null; System.gc(); // should be enqueued Reference<? extends Foo> referenceFromQueue; for (PhantomReference<Foo> reference : list) { System.out.println(reference.isEnqueued()); } // now we can call bar to do what ever it is we need done while ((referenceFromQueue = queue.poll()) != null) { ((FinalizeStuff)referenceFromQueue).bar(); referenceFromQueue.clear(); }
- 1. Việc sử dụng biến số thực tế là gì?
- 2. việc sử dụng giao diện thực tế trong java là gì?
- 3. Mục đích của việc sử dụng tham chiếu đến tham chiếu trong C++ là gì?
- 4. Việc sử dụng lời gọi phương thức ảo Java là gì?
- 5. Việc sử dụng tham chiếu const đi tới các kiểu nguyên thủy là gì?
- 6. tham chiếu cứng trong java là gì?
- 7. Tham chiếu ngược trong Java là gì?
- 8. Việc sử dụng các trường ẩn có thực tế không?
- 9. Cà ri JavaScript: các ứng dụng thực tế là gì?
- 10. Việc sử dụng thực tế biến "động" trong C# 4.0 là gì?
- 11. Ưu điểm của việc sử dụng các tham chiếu phương thức trong trường hợp này là gì?
- 12. Việc sử dụng "ref" cho biến kiểu tham chiếu trong C# là gì?
- 13. Thư mục ảo là gì? Việc sử dụng nó là gì?
- 14. Java Multi Threading - trường hợp sử dụng thực tế
- 15. Cách tham chiếu công việc trong Java
- 16. Tham chiếu `android.accounts.Account.type` là gì?
- 17. Loại tham chiếu - chúng tôi có thể xem tham chiếu thực tế không?
- 18. SQLite: giới hạn thực tế là gì?
- 19. Sự khác nhau giữa các tham chiếu và các đối tượng trong java là gì?
- 20. 'Tham chiếu toàn cầu JNI' là gì
- 21. Việc sử dụng Indexers là gì?
- 22. Việc sử dụng các chuỗi thoát dạng thức ăn và backspace trong Java là gì?
- 23. Sự khác biệt sử dụng thực tế giữa các mẫu Flyweight và Singleton là gì?
- 24. Ứng dụng thực tế trong cuộc sống là gì?
- 25. Biến tham chiếu đối tượng là gì?
- 26. Trường hợp sử dụng thực tế của cà ri là gì?
- 27. QCryptographicHash - SHA3 là gì trong thực tế?
- 28. sử dụng thực tế của IdentityHashMap trong Java 6
- 29. Việc sử dụng "khoan dung" là gì?
- 30. Việc sử dụng GADT thực tế trên thế giới