square / leakcanary

A memory leak detection library for Android.
https://square.github.io/leakcanary
Apache License 2.0
29.44k stars 3.97k forks source link

Add a fast dumper with HeapDumper API. #2387

Open alhah opened 2 years ago

alhah commented 2 years ago

Fast dump

@pyricau As we discussed in #2047 & #2121, I add a fast dumper with HeapDumper API #2237 in KOOM v2.2.0.

How to use it

  1. Add a dependency in your build.gradle

    dependencies {
    implementation "com.kuaishou.koom:koom-fast-dump:2.2.0"
    }
  2. Initialize koom fast dump and set HeapDumper, then enjoy it.

    DefaultInitTask.init(applicationContext as Application)
    LeakCanary.config = LeakCanary.config.copy(
      heapDumper = HeapDumper {
        ForkJvmHeapDumper.getInstance().dump(it.absolutePath)
      })

    Additional information

  3. Compatibility

    • Support Android L and above(API level >= 21)
    • Support armeabi-v7a arm64-v8a x86 x86-64
  4. Min Sdk The minSdkVersion of fast dump is 18. If the minSdkVersion of your app is lower than that, it needs to be compatible with overrideLibrary in the manifest.

    <uses-sdk tools:overrideLibrary="com.kwai.koom.fastdump, com.kwai.android.base, com.kwai.koom.base" />
  5. STL Support Fast dump support both shared and static libc++, if you are worried about STL conflicts, please use the static version, or you will prefer to the shared version for package size.

    dependencies {
    // In shared mode, multiple modules share the same libc++_shared.so (STL), and the package 
    // size is small, but when multiple modules depend on different STL versions, the final 
    // compilation will conflict.
    implementation "com.kuaishou.koom:koom-fast-dump:2.2.0"
    // Or in static mode, each module has its own STL, the package size is large, and there are no 
    // compilation and runtime problems.
    implementation "com.kuaishou.koom:koom-fast-dump-static:2.2.0"
    }
  6. Key logcat Please check logcat prefix with OOMMonitor to see if fast dump works.

    16743 16766 I OOMMonitor_ForkJvmHeapDumper: dump xxx.hprof.
    16743 16766 I OOMMonitor_ForkJvmHeapDumper: before suspend and fork.
    // The pid changes from 16743 to 16807, and the child process starts to dump
    16807 16807 I mple.leakcanar: hprof: heap dump "xxx.hprof" starting...
    // The child process dump finished, it takes 6.4s
    16807 16807 I mple.leakcanar: hprof: heap dump completed (24MB) in 6.411s objects 330914 objects with stack traces 0
    16807 16807 I JNIBridge: process 16807 will exit!
    // The main process is notified by the completion of the child process dump
    16743 16766 I OOMMonitor_ForkJvmHeapDumper: dump true, notify from pid 16807
pyricau commented 2 years ago

Very cool! Now we need to move this to the docs.

alhah commented 2 years ago

Very cool! Now we need to move this to the docs.

Could you please tell me what is the next plan for this?

pyricau commented 2 years ago

The plan is to add it to the doc, when myself or someone else gets to it :)

alhah commented 2 years ago

The plan is to add it to the doc, when myself or someone else gets to it :)

Looking forward to it, please let me know when it has been done, thanks :)

lujun525 commented 1 year ago

I tried to do this, but it didn't solve my problem

version: leakcanary = 2.10 minSdkVersion = 21 targetSdkVersion = 31 compileSdkVersion = 31 buildToolsVersion = '31.0.0' gradle = 7.3.3

alhah commented 1 year ago

Please describe the problem you encountered in detail and attach the logcat, thanks

lujun525 commented 1 year ago

I tried to do this, but it didn't solve my problem, my leakcanary version2.10 implementation "com.kuaishou.koom:koom-fast-dump:2.2.0"

alhah commented 1 year ago

It may be a conflict of STL versions. You can try implementing "com.kuaishou.koom:koom-fast-dump-static:2.2.0".

If it still doesn't work, please dump logcat with adb logcat > log.txt like this:

16743 16766 I OOMMonitor_ForkJvmHeapDumper: dump xxx.hprof.
16743 16766 I OOMMonitor_ForkJvmHeapDumper: before suspend and fork.
// The pid changes from 16743 to 16807, and the child process starts to dump
16807 16807 I mple.leakcanar: hprof: heap dump "xxx.hprof" starting...
// The child process dump finished, it takes 6.4s
16807 16807 I mple.leakcanar: hprof: heap dump completed (24MB) in 6.411s objects 330914 objects with stack traces 0
16807 16807 I JNIBridge: process 16807 will exit!
// The main process is notified by the completion of the child process dump
16743 16766 I OOMMonitor_ForkJvmHeapDumper: dump true, notify from pid 16807
lujun525 commented 1 year ago

2023-02-24 14:14:50.913 18972-20809/com.bstar.intl.pogo D/LeakCanary: ​

HEAP ANALYSIS RESULT
====================================
0 APPLICATION LEAKS

References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
====================================
0 LIBRARY LEAKS

A Library Leak is a leak caused by a known bug in 3rd party code that you do not have control over.
See https://square.github.io/leakcanary/fundamentals-how-leakcanary-works/#4-categorizing-leaks
====================================
0 UNREACHABLE OBJECTS

An unreachable object is still in memory but LeakCanary could not find a strong reference path
from GC roots.
====================================
METADATA

Please include this in bug reports and Stack Overflow questions.

Build.VERSION.SDK_INT: 30
Build.MANUFACTURER: vivo
LeakCanary version: 2.10
App process name: com.bstar.intl.pogo
Class count: 28936
Instance count: 261712
Primitive array count: 142221
Object array count: 33851
Thread count: 128
Heap total bytes: 33944333
Bitmap count: 116
Bitmap total bytes: 28509868
Large bitmap count: 0
Large bitmap total bytes: 0
Db 1: open /data/user/0/com.bstar.intl.pogo/databases/com.google.android.datatransport.events
Db 2: open /data/user/0/com.bstar.intl.pogo/databases/leaks.db
Db 3: closed /data/user/0/com.bstar.intl.pogo/databases/google_app_measurement_local.db
Db 4: open /data/user/0/com.bstar.intl.pogo/databases/pogo_episode.db
Stats: LruCache[maxSize=3000,hits=93350,misses=210027,hitRate=30%]
RandomAccess[bytes=11084216,reads=210027,travel=110721787370,range=39230072,size=48115957]
Heap dump reason: user request
Analysis duration: 16317 ms
Heap dump file path: /storage/emulated/0/Download/leakcanary-com.bstar.intl.pogo/2023-02-24_14-14-29_386.hprof
Heap dump timestamp: 1677219290886
Heap dump duration: 2619 ms
====================================
alhah commented 1 year ago

The hprof file has been successfully dumped, which means that it is not a problem in the dump stage, but a problem in leak analysis. The main function of koom is to improve the performance of hprof dump and avoid lagging during dump.

pyricau commented 1 year ago

This is just a case of a heap dump with no leaks in it. The user is forcing heap dumps and surprised no leaks are found.

clunyes commented 1 year ago

debugImplementation leakcanary, but this code can not compile in. release mode

alhah commented 1 year ago

Encapsulate the relevant code into a sub-library, and then use debugImplementation.

Clarklevis commented 1 year ago

Our sdk version as follows: "minSdk": 21, "compileSdk": 33, "targetSdk": 33,

and the koom version: 2.2.0 leakcanary version: 2.9.1

When encounter leaking, the logcat print as below: OOMMonitor_ForkJvmHeapDumper: dump false, notify from pid 23383 OOMMonitor_ForkJvmHeapDumper: dump /storage/emulated/0/Download/leakcanary-com.tencent.wemeet.app/2023-08-17_21-41-38_454.hprof OOMMonitor_ForkJvmHeapDumper: before suspend and fork.

Does anybody knows what make a dump false?