android内存泄漏分析 androidStudio与MAT使用

来源:互联网 发布:在淘宝怎以做代销 编辑:程序博客网 时间:2024/06/05 17:59

一.内存泄漏原因

1 单例引用context
每个activity的context是与这个activity相同的,当这个activity被释放或者被杀死是他的context会被释放掉,但是当前activity中的单例仍然存在,导致context仍然被引用不能被垃圾回收,导致内存泄漏。
2 注册没取消造成的内存泄漏
一些Android程序可能引用我们的Anroid程序的对象(比如注册机制)。即使我们的Android程序已经结束了,但是别的引用程序仍然还有对我们的Android程序的某个对象的引用,不能被垃圾回收,导致内存泄漏。
3 非静态内部类创建静态实例造成的内存泄漏
非静态内部类的生命周期是与当前类相同的而静态累的生命周期是与整个app相同的,当前类结束使并不会杀死static 的变量 ,导致非静态类的引用仍然存在,不能被垃圾回收,导致内存泄漏。
4 由线程类引发
在activity中开启自线程,当activity结束时子线程并不会被结束,如果在子线程中仍然存在对外部变量的引用也会导致内存泄漏
5 由handler引起

二 内存泄露分析

首先我们创建一个存在内存泄漏的activity

public class MainActivity2 extends Activity {    private SingleInstance singleInstance;    private IntentFilter intentFilter;    private NetworkChangeReceiver networkChangeReceiver;    private static  TextClass textClass;    private TextView text_tv;    //内存泄漏 4 由于handler引起内存泄漏    private Handler handler=new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);        }    };    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        text_tv= (TextView) findViewById(R.id.text_tv);        text_tv.setText("aaa");        //内存泄漏 1 单例引用context        singleInstance=SingleInstance.getInstance(this);        //内存泄漏2  注册广播未关闭 开启游标未关闭等 指出一个例子        intentFilter = new IntentFilter();        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");  //添加要收到的广播        networkChangeReceiver = new NetworkChangeReceiver();                    //广播实例        registerReceiver(networkChangeReceiver, intentFilter);        //内存泄漏3 非静态内部类创建静态实例造成的内存泄漏        if(textClass==null){            textClass=new TextClass();        }        //内存泄漏5 由线程类引发        new Thread(){            @Override            public void run() {                super.run();                String s=text_tv.getText().toString();            }        }.start();        handler.sendEmptyMessage(111);    }     class TextClass{    }

打开这个界面,然后返回上一界面
同过studio观察memory波动
这里写图片描述
通过这里写图片描述 来开始寻找这个界面是否存在内存溢出
等待一段时间后出现
这里写图片描述
点击右上角这里写图片描述 会出现当前的具体分析
这里写图片描述
找到问题所在,点击jump to Source 跳到出现问题的类

三 使用MAT具体分析

MAT 工具下载地址:: https://www.eclipse.org/mat/
(1)导出标准的hprof文件
这里写图片描述
(2)使用MAT打开导出文件
(3)使用这里写图片描述 输入 select * from instanceof android.app.Activity来查询是否由内存泄漏的activity
查询结果如下
这里写图片描述
果然已经被我们关闭的MainActivity2仍然出现在这里,然后我们可以去查它是否存在内存泄漏
这里写图片描述
打开后出现
这里写图片描述
果然显示textClass有问题 我们就可以去正确的改正

0 0
原创粉丝点击