• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android 如何有效的解决内存泄漏的问题,android泄漏

Android 如何有效的解决内存泄漏的问题,android泄漏

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android 内存泄漏,android检测内存泄漏,android中内存泄漏,android 检查内存泄漏,android 内存泄漏工具等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android 如何有效的解决内存泄漏的问题,android泄漏


前言:最近在研究Handler的知识,其中涉及到一个问题,如何避免Handler带来的内存溢出问题。在网上找了很多资料,有很多都是互相抄的,没有实际的作用。

本文的内存泄漏检测工具是:LeakCanary  github地址:https://github.com/square/leakcanary

 

 

什么是内存泄漏?

  • 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗。内存泄漏并不是指物理上的内存消失,这里的内存泄漏是值由程序分配的内存但是由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费。

 

怎样会导致内存泄漏?

  • 资源对象没关闭造成的内存泄漏,如查询数据库后没有关闭游标cursor
  • 构造Adapter时,没有使用 convertView 重用
  • Bitmap对象不在使用时调用recycle()释放内存
  • 对象被生命周期长的对象引用,如activity被静态集合引用导致activity不能释放

 

内存泄漏有什么危害?

  • 内存泄漏对于app没有直接的危害,即使app有发生内存泄漏的情况,也不一定会引起app崩溃,但是会增加app内存的占用。内存得不到释放,慢慢的会造成app内存溢出。所以我们解决内存泄漏的目的就是防止app发生内存溢出。

 

1、新建线程引起的Activity内存泄漏

例子:

package rxnet.zyj.com.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class Activity6 extends AppCompatActivity {

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

        findViewById( R.id.finish).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
//模拟耗时操作 Thread.sleep( 15000 ); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }

  运行上面的代码后,点击finish按钮,过一会儿发生了内存泄漏的问题。

 为什么Activity6会发生内存泄漏?

进入Activity6 界面,然后点击finish按钮,Activity6销毁,但是Activity6里面的线程还在运行,匿名内部类Runnable对象引用了Activity6的实例,导致Activity6所占用的内存不能被GC及时回收。

 

 如何改进?

Runnable改为静态非匿名内部类即可。

package rxnet.zyj.com.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class Activity6 extends AppCompatActivity {

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

        findViewById( R.id.finish).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        new Thread( new MyRunnable()).start();

    }

    private static class MyRunnable implements Runnable {

        @Override
        public void run() {
            try {
                Thread.sleep( 15000 );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
}

  

 2、Activity添加监听器造成Activity内存泄漏

package rxnet.zyj.com.myapplication;

import android.app.Activity;
import android.os.Bundle;

public class LeakActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NastyManager.getInstance().addListener(this);
    }
}

  这个是在开发中经常会犯的错误,NastyManager.getInstance() 是一个单例,当我们通过 addListener(this) 将 Activity 作为 Listener 和 NastyManager 绑定起来的时候,不好的事情就发生了。

如何改进?

想要修复这样的 Bug,其实相当简单,就是在你的 Acitivity 被销毁的时候,将他和 NastyManager 取消掉绑定就好了。

package rxnet.zyj.com.myapplication;

import android.app.Activity;
import android.os.Bundle;

public class LeakActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NastyManager.getInstance().addListener(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        NastyManager.getInstance().removeListener(this);
    }
}

  

3、Handler 匿名内部类造成内存溢出?

先看着一段代码

package rxnet.zyj.com.myapplication;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

public class HandlerActivity extends AppCompatActivity {

    private final static int MESSAGECODE = 1 ;

    private final Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.d("mmmmmmmm" , "handler " + msg.what ) ;
        }
    };

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

        findViewById( R.id.finish ).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                handler.sendEmptyMessage( MESSAGECODE ) ;
                try {
                    Thread.sleep( 8000 );
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.sendEmptyMessage( MESSAGECODE ) ;
            }
        }).start() ;

    }
}

  这段代码运行起来后,立即点击 finish 按钮,通过检测,发现 HandlerActivity 出现了内存泄漏。当Activity finish后,延时消息会继续存在主线程消息队列中8秒钟,然后处理消息。而该消息引用了Activity的Handler对象,然后这个Handler又引用了这个Activity。这些引用对象会保持到该消息被处理完,这样就导致该Activity对象无法被回收,从而导致了上面说的 Activity泄露。Handler 是个很常用也很有用的类,异步,线程安全等等。如果有下面这样的代码,会发生什么呢? handler.postDeslayed ,假设 delay 时间是几个小时… 这意味着什么?意味着只要 handler 的消息还没有被处理结束,它就一直存活着,包含它的 Activity 就跟着活着。我们来想办法修复它,修复的方案是 WeakReference ,也就是所谓的弱引用。垃圾回收器在回收的时候,是会忽视掉弱引用的,所以包含它的 Activity 会被正常清理掉。

如何避免

  • 使用静态内部类
  • 使用弱引用

修改后代码是这样的。

package rxnet.zyj.com.myapplication;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import java.lang.ref.WeakReference;

public class HandlerActivity extends AppCompatActivity {

    private final static int MESSAGECODE = 1 ;
    private static Handler handler ;

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



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android 如何有效的解决内存泄漏的问题,android泄漏

相关文章

  • 2017-05-26认清Android Studio下的Gradle是什么
  • 2017-05-26硅谷社交12--群列表页面,硅谷社交12--列表
  • 2017-05-26机顶盒上gridview+ScrollView的使用。,gridviewscrollview
  • 2017-05-26微信小程序监控,信小程序监控
  • 2017-05-26AsyncTask源码探究,asynctask源码
  • 2017-05-26Vs2017 无法调试APP,Vs2017调试APP
  • 2017-05-26Android listview和gridview以及view的区别,androidgridview
  • 2017-05-26android源码解析之(十一)--)应用进程启动流程
  • 2017-05-26Android的消息机制,Android消息机制
  • 2017-05-26Android 面试题--Activity,android--activity

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android学习笔记(26):Toast提示信息框浅析
    • MSM8909+Android5.1.1键盘驱动浅析
    • java中random随机函数的一些理解
    • redis配置文件参数解释说明
    • Android studio环境搭建,androidstudio搭建
    • Native SBS for Android,nativeandroid
    • App单个页面的最佳文本框个数是多少个?,app文本框个数
    • Android中TextView、EditText对部分内容设置不同格式(颜色、字体、超链接、图片。。)
    • 手势事件,html5手势事件
    • 单例模式——实战应用详解,单例实战详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有