Android内存泄漏检测-LeakCanary

标签: android 内存泄漏 leakcanary | 发表时间:2015-10-23 18:23 | 作者:qhshiniba
分享到:
出处:http://blog.csdn.net

square/leakcanary
udacity/Sunshine-Version-2

添加LeakCanary依赖包

在主模块app下的build.gradle下添加如下依赖:

  debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'

这里写图片描述

开启LeakCanary

添加Application子类

首先创建一个ExampleApplication,该类继承于Application,在该类的onCreate方法中添加如下代码开启LeakCanary监控:

  LeakCanary.install(this);

这里写图片描述

在配置文件中注册ExampleApplication

AndroidManifest.xml中的 application标签中添加如下信息:

  android:name=".ExampleApplication"

这里写图片描述

这个时候安装应用到手机,会自动安装一个Leaks应用,如下图:
这里写图片描述

制造一个内存泄漏的点

建立一个 ActivityManager类,单例模式,里面有一个数组用来保存 Activity

  package com.example.android.sunshine.app;

import android.app.Activity;
import android.util.SparseArray;
import android.view.animation.AccelerateInterpolator;

import java.util.List;

/**
 * Created by wuxian on 15/10/23.
 */
public class ActivityManager {
    private SparseArray<Activity> container = new SparseArray<Activity>();
    private int key = 0;
    private static ActivityManager mInstance;

    private ActivityManager(){}

    public static ActivityManager getInstance(){
        if(mInstance == null){
            mInstance = new ActivityManager();
        }

        return mInstance;
    }

    public void addActivity(Activity activity){
        container.put(key++,activity);
    }


}

然后在 DetailActivity中的 onCreate方法中将当前 activity添加到 ActivityManager的数组中:

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        ActivityManager.getInstance().addActivity(this);
        if (savedInstanceState == null) {
            // Create the detail fragment and add it to the activity
            // using a fragment transaction.

            Bundle arguments = new Bundle();
            arguments.putParcelable(DetailFragment.DETAIL_URI, getIntent().getData());

            DetailFragment fragment = new DetailFragment();
            fragment.setArguments(arguments);

            getSupportFragmentManager().beginTransaction()
                    .add(R.id.weather_detail_container, fragment)
                    .commit();
        }
    }

我们从首页跳转到详情页的时候会进入 DetailActivityonCreate的方法,然后就将当前 activity添加到了数组中,当返回时,我们没把他从数组中删除。再次进入的时候,会创建新的 activity 并添加到数组中,但是之前的 activity仍然被引用,无法释放,但是这个 activity不会再被使用,这个时候就造成了内存泄漏。我们来看看 LeakCanary是如何报出这个问题的。

演示

这里写图片描述

解析的过程有点耗时,所以需要等待一会才会在Leaks应用中,当我们点开某一个信息时,会看到详细的泄漏信息:
这里写图片描述

作者:qhshiniba 发表于2015/10/23 18:23:31 原文链接
阅读:0 评论:0 查看评论

相关 [android 内存泄漏 leakcanary] 推荐:

Android内存泄漏检测-LeakCanary

- - CSDN博客推荐文章
添加LeakCanary依赖包. 在主模块app下的build.gradle下添加如下依赖:. 添加Application子类. 首先创建一个ExampleApplication,该类继承于Application,在该类的onCreate方法中添加如下代码开启LeakCanary监控:. 在配置文件中注册ExampleApplication.

Android 解析内存泄漏

- - CSDN博客移动开发推荐文章
1、引用没释放造成的内存泄露.        1.1、注册没取消造成的内存泄露.        这种 Android的内存泄露比纯 Java的内存泄露还要严重,因为其他一些Android程序可能引用我们的Anroid程序的对象(比如注册机制). 即使我们的Android程序已经结束了,但是别的引用程序仍然还有对我们的Android程序的某个对象的引用,泄露的内存依然不能被垃圾回收.

Android性能优化之内存泄漏

- - CSDN博客推荐文章
  内存泄漏(memory leak)是指由于疏忽或错误造成程序未能释放已经不再使用的内存. 那么在Android中,当一个对象持有Activity的引用,如果该对象不能被系统回收,那么当这个Activity不再使用时,这个Activity也不会被系统回收,那这么以来便出现了内存泄漏的情况. 在应用中内出现一次两次的内存泄漏获取不会出现什么影响,但是在应用长时间使用以后,若是存在大量的Activity无法被GC回收的话,最终会导致OOM的出现.

Android性能优化之常见的内存泄漏

- - CSDN博客推荐文章
最近腾讯bugly也推出了三篇关于Android内存泄漏调优的文章,有兴趣的可以看看:. 1、 内存泄露从入门到精通三部曲之基础知识篇. 2、 内存泄露从入门到精通三部曲之排查方法篇. 3、 内存泄露从入门到精通三部曲之常见原因与用户实践. 当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏.

Android内存泄漏产生的6大原因

- - IT瘾-geek
1.资源对象没关闭造成的内存泄漏. 资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存. 它们的缓冲不仅存在于 java虚拟机内,还存在于java虚拟机外. 如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄漏.

Android内存泄漏思考 - 编程学习网

- -
Android内存泄漏是一个经常要遇到的问题,程序在内存泄漏的时候很容易导致OOM的发生. 那么如何查找内存泄漏和避免内存泄漏就是需要知晓的一个问题,首先我们需要知道一些基础知识. 强引用: 强引用是Java中最普通的引用,随意创建一个对象然后在其他的地方引用一下,就是强引用,强引用的对象Java宁愿OOM也不会回收他.

内存泄漏

- - CSDN博客系统运维推荐文章
程序申请了堆空间,但是“忘记”释放,导致该块区域在程序结束前无法被再次使用导致的. 泄漏时间长了,就会导致用户空间内存不足,严重的导致死机. 如果泄漏比较严重,很容易察觉;但是有些泄漏很缓慢,不容易察觉,但是软件会运行很长时间后,会慢慢导致严重问题,而且当发现症状的时候,基本上已经是比较晚的时候了,想要识别泄漏,还是可以实现的,本篇文章来聊聊内存操作的原理.

java内存泄漏

- - 编程语言 - ITeye博客
不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址. Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的. GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题.

浅谈Java--内存泄漏

- - ITeye博客
      JAVA的垃圾回收机制,让许多程序员觉得内存管理不是很重要,但是内存内存泄露的事情恰恰这样的疏忽而发生,特别是对于Android开发,内存管理更为重要,养成良好的习惯,有利于避免内存的泄漏..     这里可以把许多对象和引用看成是有向图,顶点可以是对象也可以是引用,引用关系就是有向边.

(转)ThreadLocal的内存泄漏问题

- - 编程语言 - ITeye博客
原文:http://www.godiscoder.com/?p=479. 在最近一个项目中,在项目发布之后,发现系统中有内存泄漏问题. 表象是堆内存随着系统的运行时间缓慢增长,一直没有办法通过gc来回收,最终于导致堆内存耗尽,内存溢出. 开始是怀疑ThreadLocal的问题,因为在项目中,大量使用了线程的ThreadLocal保存线程上下文信息,在正常情况下,在线程开始的时候设置线程变量,在线程结束的时候,需要清除线程上下文信息,如果线程变量没有清除,会导致线程中保存的对象无法释放.