Android의 LeakCanary 원리 분석

시나리오: 최신 누출Canary2.8.1:

debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'

원칙: 우선 최신 종속성 패키지를 도입하고 있으며 초기화는 매니페스트 파일에 contentProvider()를 등록하고 onCreate()에 초기화를 넣어 초기화하기 때문에 아무것도 할 필요가 없습니다. 프로세스에서 그는 응용 프로그램을 사용하여 활동 및 프래그먼트와 같은 개체의 수명 주기 변화를 모니터링하고 관찰합니다.파괴 수명 주기가 실행되면 해당 ActivityWatch--->ObjectWatch를 사용하여 파괴된 것을 관찰합니다. 객체, 그래서 그것을 관찰하는 방법?? 개체를 약한 참조 개체에 추가하고 이 약한 참조를 참조 큐 Queue에 바인딩합니다(동시에 이 약한 참조를 맵 관찰 목록에 먼저 추가). 활성화된 Gc에서 누수가 없으면 활동 관찰 개체를 재활용하고 이 약한 참조를 참조 큐에 추가합니다. 참조 큐에 값이 있는지 여부를 판단할 수 있습니다. 누출된 경우 누출된 개체의 약한 참조가 집합에 추가됩니다. 마지막으로 상어 라이브러리(원래 하하 분석 라이브러리)를 이용해 유출된 장소를 쿼리해 덤프 파일을 생성하고 분석 결과를 개발자에게 알려준다.

알림 클릭: 보유 객체 알림---클릭 -->힙 덤프---자동 -->힙 분석 중

이 분석 결과를 보는 방법:

 위의 두 그림은 누수 개체의 참조 체인 관계이며 마지막으로 누수 개체 LoginActivity가 있으므로 누수를 검색해야 하는 이유는 컨텍스트(즉, LoginActivity 개체)가 유지됨을 알 수 있습니다. Dialog 싱글톤에서 시간이 지남에 따라 사라집니다. Destory는 항상 GcRoot에 의해 유지되기 때문에 이 개체를 파괴하지 않습니다.

 메모리 누수를 일으키는 코드는 다음과 같습니다.

object LoadingDialog {


    //内部生成的时候,根据INSTANCE 看起来感觉是静态,因为可以LoadingDialog.show()
    //其实是伪静态
    fun show() {

    }

    //这种写法才是静态方法
    @JvmStatic
    fun show2() {

    }

    private var dialog:Dialog?=null

    fun show(context: Context) {

        cancel()
        dialog = Dialog(context)
        dialog?.setContentView(R.layout.dialog_loading)
        dialog?.setCancelable(false)
        dialog?.setCanceledOnTouchOutside(false)
        dialog?.show()

    }

    fun cancel() {
        dialog?.dismiss()
    }

}

해결 방법은 대화 상자를 모두 사용했을 때 null로 설정하는 것입니다.

fun cancel() {
        dialog?.dismiss()
        dialog = null;
    }

이런 식으로 leakCanary는 누출 지점을 알리지 않습니다.

Supongo que te gusta

Origin blog.csdn.net/sunbinkang/article/details/122951794
Recomendado
Clasificación