Thành phần điều hướng Arch có thể tạo ra một rò rỉ bộ nhớ dương sai?


14

Tôi có kiến ​​thức cơ bản về rò rỉ bộ nhớ và những gì có thể gây ra chúng. Đó là lý do tại sao tôi không hiểu nếu tôi gặp vấn đề trong mã của mình hoặc đó là dương tính giả. Tôi không biết phần nào của mã tôi nên chia sẻ vì dự án không nhỏ. Nhưng chỉ cần cho tôi biết trong các ý kiến ​​và tôi sẽ thêm mã yêu cầu.

Tôi sử dụng thành phần vòm điều hướng và theo mô hình MVVM. Tôi đã thêm thư viện LeakCanary sau này trong quá trình phát triển dự án và nó ngay lập tức bắt đầu đưa ra cảnh báo cho tôi về các trường hợp được giữ lại khi tôi điều hướng giữa các màn hình.

Vấn đề xảy ra khi tôi thêm các mảnh vào ngăn xếp trở lại. Với mỗi mảnh được thêm vào ngăn xếp phía sau, bộ đếm của các thể hiện được giữ lại tăng lên. Khi nó đạt đến giá trị ngưỡng của 5 LeakCanary sẽ bỏ đống và cung cấp báo cáo.

Nhưng nếu tôi nhấp vào nút quay lại và quay lại màn hình trước thì bộ đếm của các trường hợp được giữ lại sẽ giảm và cuối cùng, khi trở lại màn hình thứ nhất, tất cả các trường hợp được giữ lại sẽ biến mất.

Nếu tôi nhìn vào các báo cáo phân tích heap, nó nói rằng bộ điều phối biếnLayout có tham chiếu đến CoordinatorLayoutxml đã bị rò rỉ. Nếu tôi loại bỏ biến và tất cả việc sử dụng nó và chạy lại ứng dụng, tôi sẽ thấy vấn đề tương tự, nhưng bây giờ với một biến khác là tham chiếu đến một chế độ xem khác trong xml. Tôi đã cố xóa tất cả các lượt xem và cách sử dụng của chúng mà LeakCanary báo cáo là bị rò rỉ. Khi nó nói rằng a TextView, chỉ được sử dụng để đặt văn bản onViewCreatedvà không được sử dụng ở bất kỳ nơi nào khác, tôi bị rò rỉ, tôi bắt đầu nghi ngờ rằng có một vấn đề trong mã của mình.

Tôi đã phân tích các cuộc gọi phương thức vòng đời theo từng mảnh và nhận thấy rằng khi tôi điều hướng đến màn hình mới cho đoạn trước đó, tất cả các phương thức cho đến khi onDestroyViewđược gọi nhưng không được gọi onDestroy. Khi tôi nhấp trở lại onDestroyđược gọi cho đoạn nằm trên đỉnh ngăn xếp trở lại và bộ đếm giữ lại giảm.

Tôi nghi ngờ rằng thành phần Điều hướng đang giữ ví dụ của một đoạn khi nó nằm trong ngăn xếp phía sau và LeakCanary đang xem nó là một rò rỉ.

Câu trả lời:


24

Đó là cách Fragment trên stack back hoạt động (và Navigation chỉ sử dụng API Fragment hiện có): chế độ xem của Fragment bị phá hủy, nhưng chính Fragment không bị phá hủy - chúng được giữ ở CREATEDtrạng thái cho đến khi bạn nhấn nút quay lại và quay lại Fragment (sau đó onCreateView()sẽ được gọi lại và bạn sẽ chuyển trở lại RESUMED).

Theo các đoạn: Cuộc nói chuyện trong quá khứ, hiện tại và tương lai , một trong những thay đổi trong tương lai đến với Mảnh vỡ là một lựa chọn không thể phá hủy Mảnh vỡ ở ngăn xếp phía sau, thay vì có hai vòng đời riêng biệt. Điều này là không có sẵn cho đến nay.

Bạn phải loại bỏ các tham chiếu của mình đến các chế độ xem onDestroyViewvì đó là dấu hiệu cho thấy chế độ xem không còn được sử dụng bởi hệ thống Fragment và nó có thể được thu gom rác một cách an toàn nếu không tiếp tục tham khảo Chế độ xem.


2
Android View Binding có giải quyết được vấn đề này không? Tôi không thể tìm thấy bất kỳ tài liệu nào về việc tham chiếu đến các chế độ xem Binding (có thể là chính đối tượng ràng buộc) có tự động 'bị loại bỏ' trong onDestroyViewChế độ xem liên kết hay không.
Tim Malseed

3
@TimMalseed - bạn cần tự hủy tham chiếu đến đối tượng ràng buộc, không có gì tự động xảy ra.
ianhanniballake

1
@Emmanuel - bạn cần thả tham chiếu của mình vào chính đối tượng ràng buộc vì nó giữ một tham chiếu cứng cho các Chế độ xem mà nó sở hữu.
ianhanniballake

1
@Emmanuel - bạn luôn có thể gửi yêu cầu tính năng !
ianhanniballake

1
@Emmanuel - Tôi nghĩ rằng đó chắc chắn sẽ là một sự thay đổi trong hành vi (có thể ám chỉ nó là một lựa chọn riêng biệt trong cờ), nhưng có LifecyclOwner chính xác sẽ đủ thông tin để nó khắc phục toàn bộ vấn đề bộ nhớ.
ianhanniballake
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.