leakcanary는android8에 있습니다.0의 작은 실험
조사 연구 leakcanary 참조 링크는 다음과 같습니다.https://www.liaohuqiu.net/cn/posts/leak-canary-read-me/https://github.com/square/leakcanaryleakcanary는android 메모리 유출 모니터링 도구로 약한 인용 대기열을 이용한다.작업 메커니즘은 다음과 같다. 작업 절차1.RefWatcher.watch () 는 감시할 대상에 KeyedWeakReference를 만듭니다.2. 백엔드 라인에서 인용이 삭제되었는지 확인하고 없으면 GC를 호출합니다.3. 인용이 삭제되지 않으면 APP에 대응하는 파일 시스템 중 하나에 heap 메모리 덤프를 넣습니다.hprof 파일에서4. 다른 프로세스의 HeapAnalyzer Service에는 HAHA를 사용하여 파일을 처리하는 HeapAnalyzer가 있습니다.5. 유일한 Reference 키 덕분에 Heap Analyzer가 Keyed Weak Reference를 찾아 메모리 유출을 포지셔닝했다.6. HeapAnalyzer는 GC 루트의 가장 짧은 참조 경로를 계산하고 유출 여부를 확인합니다.그렇다면 유출을 초래하는 인용체인을 구축한다.7. 인용체인이 앱 프로세스에 전달된 DisplayLeakService를 알림 형식으로 보여준다.
사용 과정 중build을 설정합니다.gradle (당신의 앱이 전역적이지 않다는 것을 주의하십시오)
dependencies{
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
}
실험 코드는 다음과 같다. 정적 대상이 일으킨 메모리 유출(사용자 정의 대상의 모니터링, 응용 프로그램을 스스로 계승해야 함)
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.squareup.leakcanary.*;
class Cat {
String name;
Cat(String _name){
name=_name;
}
}
class Box {
Cat hiddenCat;
}
class schrodinger{
static Box hisbox;
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Box box = new Box();
Cat schrodingerCat = new Cat("caffe");
box.hiddenCat = schrodingerCat;
schrodinger.hisbox = box;
RefWatcher ref = myapplication.getRefWatcher(this);
ref.watch(schrodingerCat);
}
}
leakcanary 중 일부 코드 분석:watch 방법:
@Synchronized fun watch(
watchedReference: Any,
referenceName: String
) {
removeWeaklyReachableReferences()
//
val key = UUID.randomUUID()
.toString()
// key
val watchUptimeMillis = clock.uptimeMillis()
//
val reference =
KeyedWeakReference(watchedReference, key, referenceName, watchUptimeMillis, queue)
//
if (referenceName != "") {
CanaryLog.d(
"Watching instance of %s named %s with key %s", reference.className,
referenceName, key
)
} else {
CanaryLog.d(
"Watching instance of %s with key %s", reference.className, key
)
}
watchedReferences[key] = reference
// map key
checkRetainedExecutor.execute {
moveToRetained(key)
}
}
누설 모니터링:
fun detectLeaks(): Result {
val leakDetectionTime = SystemClock.uptimeMillis()
val watchDurationMillis = LeakSentry.config.watchDurationMillis
val instrumentation = getInstrumentation()
val context = instrumentation.targetContext
val refWatcher = LeakSentry.refWatcher
if (!refWatcher.hasWatchedReferences) {
return NoAnalysis
}
instrumentation.waitForIdleSync()
if (!refWatcher.hasWatchedReferences) {
return NoAnalysis
}
runGc()// GC
if (!refWatcher.hasWatchedReferences) {
return NoAnalysis
}
// Waiting for any delayed UI post (e.g. scroll) to clear. This shouldn't be needed, but
// Android simply has way too many delayed posts that aren't canceled when views are detached.
SystemClock.sleep(2000)
if (!refWatcher.hasWatchedReferences) {
return NoAnalysis
}
// Aaand we wait some more.
// 4 seconds (2+2) is greater than the 3 seconds delay for
// FINISH_TOKEN in android.widget.Filter
SystemClock.sleep(2000)
val endOfWatchDelay = watchDurationMillis - (SystemClock.uptimeMillis() - leakDetectionTime)
if (endOfWatchDelay > 0) {
SystemClock.sleep(endOfWatchDelay)
}
runGc()// GC
if (!refWatcher.hasRetainedReferences) {
return NoAnalysis
}
// dump...
}
전재 대상:https://www.cnblogs.com/zhangxianlong/p/10720197.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.