LeakCanaryオープンソースプロジェクト

6553 ワード

先日、Squareはメモリリーク自動探知神器のLeakCanaryから源を発しました。AndroidとJavaのメモリリーク検出ライブラリです。開発中に遭遇したOOM問題を大幅に減らすことができます。開発者にとっては、間違いなく福音です。以下はこのライブラリのreadmeを簡単に翻訳します。
「A small leak will sink a great ship.」ベンジャミンフランクリン
Getting started
プロジェクトのbuild.gradleファイルに追加:
 dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
 }
アプリクラスで追加:
public class ExampleApplication extends Application {

  @Override public void onCreate() {
    super.onCreate();
    LeakCanary.install(this);
  }
}
あなたのdebug構築中にメモリ漏れが発生した場合、LeakCanaryは自動的に通知欄を表示します。
なぜ私はLeakCanaryを使うべきですか?
よく聞きました私たちはちょうどブログを書いてこの質問に答えました。
それはどう使いますか?
RefWatchを使って、いつGCに引用されるべきかを観察します。
RefWatcher refWatcher = {...};

// We expect schrodingerCat to be gone soon (or not), let's watch it.
refWatcher.watch(schrodingerCat);
LeakCanary.install()は、以前に設定されたRefWatchを返します。ActivityRefWatchもインストールして、Activity.onDestroy()が呼び出された後、Activityが漏洩したかどうかを自動的に検出します。
public class ExampleApplication extends Application {

  public static RefWatcher getRefWatcher(Context context) {
    ExampleApplication application = (ExampleApplication) context.getApplicationContext();
    return application.refWatcher;
  }

  private RefWatcher refWatcher;

  @Override public void onCreate() {
    super.onCreate();
    refWatcher = LeakCanary.install(this);
  }
}
RefWatchを使ってFragmentのメモリ漏れを観察できます。
public abstract class BaseFragment extends Fragment {

  @Override public void onDestroy() {
    super.onDestroy();
    RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity());
    refWatcher.watch(this);
  }
}
How does it work
1.RefWatch.watch()KeyedWeak Referenceを作成して、対象を検査します。2.バックグラウンドスレッドでは、GCトリガではない場合には、参照がクリアされる必要があるかどうかを確認します。3.引用引用引用がまだクリアされていない場合は、システムファイルにhprofファイルを蓄積します。hprofファイルはシステムファイルの中で(it them dumps the heap into a.hprof file stored on the ap file system.)4.HeappAnalyzer Serviceは分離の過程で始まります。5.特殊な引用keyと位置付けの漏洩引用のため、HeappAnalyzerはheap dumpでKeyedWeak Referenceを見つけることができます。6.もし漏れがあったら、HeappAnalyzerはGC Rootsまでの最短の強い引用経路を計算して、漏れの原因となる参照チェーンを作成する。7.結果はappのプロセスでDisplayLeakServiceに戻り、漏洩した通知メッセージを示す。
leak traceはどうやってコピーしますか?
Logcatでleak traceを見ることができます。
In com.example.leakcanary:1.0:1 com.example.leakcanary.MainActivity has leaked:
* GC ROOT thread java.lang.Thread. (named 'AsyncTask #1')
* references com.example.leakcanary.MainActivity$3.this$0 (anonymous class extends android.os.AsyncTask)
* leaks com.example.leakcanary.MainActivity instance

* Reference Key: e71f3bf5-d786-4145-8539-584afaecad1d
* Device: Genymotion generic Google Nexus 6 - 5.1.0 - API 22 - 1440x2560 vbox86p
* Android Version: 5.1 API: 22
* Durations: watch=5086ms, gc=110ms, heap dump=435ms, analysis=2086ms
leak traction barのメニューを通じてleak traceとheap dumpファイルを共有することもできます。
My leak is caused by the SDK implemention!
時間が経つにつれて、多くのよく知られているメモリリーク問題はメーカーによって、androidオープンソースプロジェクトで修復されます。このようなリークが発生すると、アプリケーション開発者として修復することができます。このため、LeakCanaryはAndroidリークのリストを内蔵しています。Android dExcludRefs.javaで監視しています。もし新しいリークが見つかったら、leaktraceでissueを作成して、デバイスとAndroidのバージョンを明示してください。もしあなたがheap dumpのファイルリンクを提供したらもっといいです。
これは新発売のAndroidバージョンにとって特に重要です。新しいメモリの漏洩を検出するのにもっと早い機会があります。これはAndroidコミュニティ全体に有益です。開発版のスナップショットはSonappype's snapshots repositoryで見つけられます。
Beyond the leak trace
時にはleak traceがあまりはっきりしない場合、MATとYourKitを使ってheap dumpを深く研究する必要があります。ここでどのようにhead dumpで漏れの例を見つけられるか教えます。
1.カバンのcomp.squareup.leakcanary.KeyedWeak Referenceの全ての例を探し出します。2.各例について、そのkeyドメインを考慮する。3.KeyedWeak Referenceを見つけるには、LeakCanaryによって報告された引用のkeyに等しいkeyドメインがあります。4.KeyedWeak Referenceのreferentドメインはプログラム中のメモリ漏れの対象です。5.その時から、問題はあなたの手に移りました。良いスタートは最も短いGC rootsのパスを見つけることです(弱い参照を除く)。
Custoomizingをカスタマイズします。
アイコンとラベルIcon and label
Displaplay LeakActivityは標準のiconとlabelを持参して、提供するR.drawableを通じて(通って)ことができます。leak_canaryiconとR.string._uleak_canarydisplay_activitylabelを変更します
res/
  drawable-hdpi/
    __leak_canary_icon.png
  drawable-mdpi/
    __leak_canary_icon.png
  drawable-xhdpi/
    __leak_canary_icon.png
  drawable-xxhdpi/
    __leak_canary_icon.png
  drawable-xxxhdpi/
    __leak_canary_icon.png


  MyLeaks

ストックleak traces
DisplayLeakActivityはあなたのappディレクトリに7つのheap dumpsとleak traccesを保存できます。あなたはappでR.integerを提供します。leak_canarymax_stored_leaksの値はこの数量を変更します。


  20

サーバにアップロード
デフォルトの行動を変更して、leak traceをアップロードして、heap dumpを選択したサーバにアップロードすることができます。あなた自身のAbstractAnalysis Result Serviceを作成します。一番簡単な方法はあなたのdebugのソースコードの中でDefault Analysis Result Serviceを継承することです。
public class LeakUploadService extends DefaultAnalysisResultService {
  @Override protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) {
    if (!result.leakFound || result.excludedLeak) {
      return;
    }
    myServer.uploadLeakBlocking(heapDump.heapDumpFile, leakInfo);
  }
}
あなたが正式に発表したAppleクラスでRefWatchを無効にすると確定しました。
public class ExampleApplication extends Application {

  public static RefWatcher getRefWatcher(Context context) {
    ExampleApplication application = (ExampleApplication) context.getApplicationContext();
    return application.refWatcher;
  }

  private RefWatcher refWatcher;

  @Override public void onCreate() {
    super.onCreate();
    refWatcher = installLeakCanary();
  }

  protected RefWatcher installLeakCanary() {
    return RefWatcher.DISABLED;
  }
}
あなたのdebugのAppleクラスでカスタマイズされたRefWatchを作成します。
public class DebugExampleApplication extends ExampleApplication {
  protected RefWatcher installLeakCanary() {
    return LeakCanary.install(app, LeakUploadService.class);
  }
}
あなたのdebugのmanifestにserviceを登録したことを忘れないでください。


  
    
  

cfanr