Android内存泄漏检测-LeakCanary

标签: android 内存泄漏 leakcanary | 发表时间:2015-10-24 02: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 轻松解决内存泄漏

- - IT瘾-jianshu
方法区(non-heap):编译时就分配好,在程序整个运行期间都存在. 栈区:当方法执行时,会在栈区内存中创建方法体内部的局部变量,方法结束后自动释放内存;. 堆区(heap):通常用来存放 new 出来的对象. Java四种不同的引用类型. 强引用(Strong Reference):JVM 宁愿抛出 OOM,也不会让 GC 回收存在强引用的对象.

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

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

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

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

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

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

Android 性能篇 -- 带你领略Android内存泄漏的前世今生

- - SegmentFault 最新的文章
内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗. 内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存但是由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费. Java 程序运行时的内存分配策略有三种,分别是. 静态分配 、 栈式分配 和. 堆式分配 ,对应的三种存储策略使用的内存空间主要分别是.

内存泄漏

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

java内存泄漏

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