2011-12-12 27 views
17

Tôi đã đọc câu hỏi này mà chỉ bị hỏi: Avoid memory leaks in callbacks?Trình nghe ẩn danh có tương thích với các tham chiếu yếu không?

Và tôi khá bối rối, cho đến khi một người nào đó đã trả lời như sau:

"Vấn đề với phương pháp này là bạn không thể có một người biết lắng nghe mà chỉ tham chiếu trong bộ sưu tập vì nó sẽ biến mất một cách ngẫu nhiên (trên GC tiếp theo)"

tôi thích hợp trong hiểu biết của tôi rằng việc sử dụng một tài liệu tham khảo yếu, giống như khi lưu trữ trong một WeakHashMap, không tương thích với thính giả vô danh?

tôi thường vượt qua người nghe như thế này:

public static void main(String[] args) { 
    final Observable obs = new SomeObservable(); 
    obs.addObserver(new Observer() { 
     public void update(final Observable o, final Object arg) { 
      System.out.println("Notified"); 
     } 
    }); 
    obs.notifyObservers(); 
    ... // program continues its life here 
} 

private static final class SomeObservable extends Observable { 

    @Override 
    public void addObserver(final Observer o) { 
     super.addObserver(o); 
     setChanged(); // shouldn't be done from here (unrelated to the question) 
    } 

} 

Và tôi tiếp tục theo dõi những người nghe sử dụng một CopyOnWriteArrayList (mặc định Quan sát trên dường như sử dụng một tuổi Vector nhưng nó chỉ là một ví dụ để cho thấy cách tôi thường tạo một lớp ẩn danh để sử dụng như một người nghe).

Là câu hỏi tiền thưởng: khi nào tham chiếu đến người nghe nặc danh đủ điều kiện tham gia GC nên chủ thể quan sát có thể sử dụng WeakHashMap không? Khi chính thoát khỏi phương pháp? Ngay sau khi cuộc gọi kết thúc obs.addObserver?

Tôi hơi bối rối về vị trí/cách thức/khi tham chiếu đến các phiên bản lớp ẩn danh được lưu trữ/lưu trữ/dễ hiểu đối với GC. Rõ ràng nếu tôi giữ một tài liệu tham khảo bình thường, nó không đủ điều kiện cho GC, nhưng khi nào nó nằm trong WeakHashMap, khi nào thì chính xác người nghe trở nên dễ hiểu cho GC?

Trả lời

3

Nếu một đối tượng chỉ là chìa khóa của WeakHashMap, thì nó đủ điều kiện và có khả năng làm sạch trên GC tiếp theo.

Toàn bộ ý tưởng sử dụng bộ sưu tập được tham chiếu yếu, là loại bỏ hoàn toàn trình nghe không còn được tham chiếu. (Điều này tránh được khả năng rò rỉ bộ nhớ) Vấn đề là người nghe có thể được loại bỏ sớm và tại một thời điểm "ngẫu nhiên" trong thời gian.

+1

Cảm ơn sự giúp đỡ của bạn, tôi hiểu điều đó.Nhưng câu hỏi của tôi thực sự liên quan đến cụ thể đối với những người nghe nặc danh: nếu tôi đặt một tham chiếu đến một người nghe nặc danh trong một WeakHashMap, có một tham chiếu nào khác cho người nghe nặc danh đó được giữ ở một nơi khác không? Nếu không, tại thời điểm nào trở nên dễ hiểu cho GC? Sau cuộc gọi nào? –

6

Có, bạn nói đúng, một lớp học có thể nghe được duy trì người nghe có tham chiếu yếu (cũng như WeakHashMap) yêu cầu sự kiên trì độc lập của họ. Có thể được sử dụng cho hệ thống phân cấp người nghe trong đó người nghe có con và cha mẹ.

Để không sử dụng WeakReference, hãy xóa một trình gỡ bỏ rõ ràng. Trừ khi đối tượng nghe có thể sống miễn là đối tượng nghe được. Trong hầu hết các trường hợp sử dụng đó là tốt, và một lớp vô danh sẽ làm.

Với trường hợp ẩn danh, lỗi bị rò rỉ (Phòng ngừa GC) chỉ có thể xảy ra khi truy cập đối tượng cuối cùng bên ngoài nội dung lớp học.

Lưu ý: WeakHashMap i.a. sử dụng tham chiếu yếu cho lớp con của riêng Map.Entry. Mà đôi khi có thể được khá tâm boggling.

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