如何使用泄漏金丝雀

新手上路,请多包涵

我目前在我的应用程序中遇到 OutOfMemoryError。我曾尝试使用 MAT 进行调试,但仍然很难在一些活动中找到漏洞。然后我找到了 LeakCanary,它看起来更简单易用,但是我找不到任何关于使用 Leak Canary 的初学者分步指南,即使在 Google 上也是如此。我已经通过我的 build.gradle 中的依赖项安装了 LeakCanary,这是我到目前为止得到的:

ExampleApplication.java

 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);
    }

    final class KeyedWeakReference extends WeakReference<Object> {
        public final String key;
        public final String name;

        KeyedWeakReference(Object referent, String key, String name,
                       ReferenceQueue<Object> referenceQueue) {
            super(checkNotNull(referent, "referent"), checkNotNull(referenceQueue, "referenceQueue"));
            this.key = checkNotNull(key, "key");
            this.name = checkNotNull(name, "name");
        }
    }

    public void watch(Object watchedReference, String referenceName) {
        checkNotNull(watchedReference, "watchReference");
        checkNotNull(referenceName, "referenceName");
        if(debuggerControl.isDebuggerAttached()) {
            return;
        }
        final long watchStartNanoTime = System.nanoTime();
        String key = UUID.randomUUID().toString();
        retainedKeys.add(key);
        final KeyedWeakReference reference =
            new KeyedWeakReference(watchedReference, key, referenceName, queue);
        watchExecutor.execute()

    }
}

假设我有一个 Activity,我希望 LeakCanary 在其中监视一个对象

SampleActivity.java

 public class SampleActivity extends Activity implements View.OnClickListener {
    ImageView level001, level002;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.choose_level);

        level001 = (ImageView) findViewById(R.id.level001);
        level002 = (ImageView) findViewById(R.id.level002);

        // Do all kinds of functions
        // How do I use LeakCanary to watch these objects?

    }
}

现在我如何使用 LeakCanary 来查看哪个对象导致内存泄漏?

原文由 Charas 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 340
1 个回答

泄漏金丝雀的好处在于它的工作自动化程度。默认情况下,它已经“监视”了未正确进行 GC 处理的活动。所以开箱即用,如果有任何活动泄漏,您应该会收到通知。

在我的项目中,我在 Application 上添加了一个额外的方法,如下所示:

 public class ExampleApplication extends Application {
    public static ExampleApplication instance;
    private RefWatcher refWatcher;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        refWatcher = LeakCanary.install(this);
    }

    public void mustDie(Object object) {
        if (refWatcher != null) {
            refWatcher.watch(object);
        }
    }
}

所以关于垃圾收集和内存泄漏以及金丝雀的重要内容是知道什么时候应该收集东西并要求监视该项目。

例如,我们使用带有以下代码的“基本片段”:

 @Override
public void onDestroy() {
    super.onDestroy();
    ExampleApplication.instance.mustDie(this);
}

这种方式 LeakCanary 正在尝试检查是否有任何片段正在泄漏内存。

因此,为了进一步在您的应用程序上实施,您可以/应该在您知道它应该被垃圾收集但您认为它可能不是,并且您不确定在哪里的任务或实例上,您也可以调用它: ExampleApplication.instance.mustDie(object);

然后你必须运行应用程序并旋转设备并强制发生泄漏,因此泄漏金丝雀可以获取/分析堆栈跟踪并为你提供有关如何修复它的宝贵信息。

我希望它有所帮助。

原文由 Budius 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题