Navigation Arch Component가 오 탐지 메모리 누출을 생성 할 수 있습니까?


14

메모리 누수와 그 원인에 대한 기본 지식이 있습니다. 그렇기 때문에 코드에 문제가 있거나 거짓 긍정인지 이해하지 못합니다. 프로젝트가 작지 않기 때문에 코드의 어느 부분을 공유해야하는지 모르겠습니다. 그러나 의견에 알려 주면 필요한 코드를 추가 할 것입니다.

탐색 아치 구성 요소를 사용하고 MVVM 패턴을 따릅니다. 나중에 프로젝트 개발에서 LeakCanary 라이브러리를 추가했으며 화면 간을 탐색 할 때 보유 인스턴스에 대한 경고를 즉시 표시하기 시작했습니다.

백 스택에 조각을 추가하면 문제가 발생합니다. 백 스택에 추가 된 각 조각으로 보유 인스턴스의 카운터가 증가합니다. 임계 값이 5 인 LeakCanary에 도달하면 힙을 덤프하고 보고서를 제공합니다.

그러나 뒤로 버튼을 클릭하고 이전 화면으로 돌아 가면 보유 인스턴스의 카운터가 감소하고 결국 첫 번째 화면으로 돌아 가면 모든 보유 인스턴스가 사라집니다.

힙 분석 보고서를 보면 CoordinatorLayoutin xml에 대한 참조 인 변수 coordinatorLayout 이 누출 되었다고 말합니다 . 변수와 모든 사용법을 제거하고 앱을 다시 실행하면 동일한 문제가 발생하지만 xml의 다른보기에 대한 참조 인 다른 변수가 있습니다. LeakCanary가 유출 한 것으로보고 한 모든 뷰와 그 사용법을 제거하려고했습니다. 그것이라고하면 TextView그냥 텍스트를 설정하는 데 사용되는, onViewCreated하지 다른 곳에서는 사용, 내 코드에서 문제가 있음을 의심하기 시작 누출된다.

나는 프래그먼트에서 라이프 사이클 메소드 호출을 분석하고 이전 프래그먼트의 새 화면으로 이동할 때까지를 포함한 모든 메소드 onDestroyView가 호출되지만 호출되지 않는 것을 알았 습니다 onDestroy. 다시 클릭하면 onDestroy백 스택 맨 위에 있던 조각이 호출되고 보유 인스턴스 카운터가 감소합니다.

탐색 구성 요소가 백 스택에있을 때 조각의 인스턴스를 유지하고 LeakCanary가 누출로보고 있다고 의심합니다.

답변:


24

백 스택의 프래그먼트가 작동하는 방식입니다 (Navigation은 기존 프래그먼트 API를 사용합니다). 프래그먼트의 뷰는 파괴되지만 프래그먼트 자체는 파기되지 않습니다-Back CREATED버튼을 누르고 프래그먼트로 돌아올 때까지 상태 가 유지됩니다 (이후 onCreateView()다시 호출되며으로 다시 돌아갑니다 RESUMED).

당으로 조각 : 과거, 현재, 그리고 미래의 이야기 , 미래의 한 변경 조각에 오는 것이 아니라 두 개의 분리 된 라이프 사이클을하는 것보다, 백 스택에 조각을 파괴하는 옵션 선택 하이다. 아직 사용할 수 없습니다.

당신의 견해로 참조를 null로가 onDestroyView그 뷰가 조각 시스템에 의해 더 이상 사용되고 있다는 징조로하고 그것은보기에 여러분의 지속적인 참조 아니었다면 안전 쓰레기 수집 할 수 있습니다.


2
Android View Binding이이 문제를 해결합니까? View Binding 뷰 (참조 바인딩 개체 자체)에 대한 참조가 View Binding으로 자동으로 '널 아웃'되는지 여부에 대한 문서를 찾을 수 없습니다 onDestroyView.
Tim Malseed

3
@TimMalseed-바인딩 객체에 대한 참조를 null로 지정해야하며 자동으로 진행되는 것은 없습니다.
ianhanniballake

1
@ Emmanuel-바인딩 객체 자체에 대한 참조를 삭제해야합니다.
ianhanniballake

1
@ Emmanuel-언제든지 기능 요청을 제출할 수 있습니다 !
ianhanniballake

1
@ Emmanuel-그것은 분명히 행동의 변화 일 것이라고 생각합니다 (이것은 별도의 opt in 플래그를 의미 할 수 있습니다). 그러나 올바른 LifecycleOwner가 있으면 전체 메모리 문제를 해결하기에 충분한 정보가 될 것입니다.
ianhanniballake
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.