android开发中遇到的内存泄露(非大众版)

http://www.cnblogs.com/leftwing/archive/2012/02/09/2343420.html

本来想早点睡觉的,这些天睡眠不足啊,弄这个内存泄露的问题压力太大了,但是还是先记录下来才能踏实 %><%

这几天被师父派了个处理内存泄露的任务。先说说状况,在eclipse中可以通过DDMS的heap来查看程序在内存中的占用情况。而我要处理的这个程序,每次运行后退出,都会使得allocated项增加0.1M,这样反复运行几百次之后,程序就会砰的一下,崩溃了---

 

于是就开始找问题。用到了一款工具——MAT,是用来分析内存问题的,这个网上一搜也一大堆,用法也一大堆,所以我就不多说了。以前没用过这个,不知道是这个软件自身功能的限制,还是我没摸透他的功能,反正通过mat只是找出来了一点点很笼统的提示,最大的问题之一就是MessageQueue有问题,那我就在偌大的工程中去找Message啊、Handler之类的相关代码吧。

 

一下子就花了三天的时间,因为实在是不知道在哪会出现什么样的问题,最后是通过自己写了几个小程序,模拟了一下Handler的几种用法,才发现的问题。正常用下来的话,handleMessage()基本上不会出什么问题;平常的用一下postDelayed()也不会出什么问题;但是postDelayed()嵌套就会有问题了。

先来个造成问题的代码(灰常的简单,只是为了演示一下问题):

 1 package example.HandlerTest;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 
 7 public class HandlerTest extends Activity {
 8 
 9     Handler handler=new Handler();
10     
11     /** Called when the activity is first created. */
12     @Override
13     public void onCreate(Bundle savedInstanceState) {
14         super.onCreate(savedInstanceState);
15         setContentView(R.layout.main);
16         
17         handler.postDelayed(new Runnable() {
18             
19             @Override
20             public void run() {
21                 // TODO Auto-generated method stub
22                 System.out.println(this.toString());
23                 
24                 //这里是问题的所在
25                 handler.postDelayed(this, 2000);
26             }
27         }, 2000);
28     }
29     
30 }

在postDelayed()里面,重写的run方法中又有一个postDelayed(),这样就会造成程序返回或者activity关闭的时候,后台仍然会有一个线程在跑,上个效果图:

这是我运行两次后的输出结果,程序退出了,后台仍然有两个线程在跑,无法被释放,如果是大程序,就会导致:一、耗电;二、内存泄露。

解决方法:

在程序销毁的时候,要通过Handler的removeCallbacks(Runnable r)方法来手动释放掉该线程,当然要把Runnable单独提出来写,再来个修改后的代码:

 1 package example.HandlerTest;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 import android.view.KeyEvent;
 7 
 8 public class HandlerTest extends Activity {
 9 
10     Handler handler=new Handler();
11     
12     /** Called when the activity is first created. */
13     @Override
14     public void onCreate(Bundle savedInstanceState) {
15         super.onCreate(savedInstanceState);
16         setContentView(R.layout.main);
17         
18         handler.postDelayed(handlerRunnable, 2000);
19     }
20 
21     @Override
22     protected void onDestroy() {
23         // TODO Auto-generated method stub
24         handler.removeCallbacks(handlerRunnable);
25         super.onDestroy();
26     }
27 
28 
29 
30     Runnable handlerRunnable=new Runnable() {
31         
32         @Override
33         public void run() {
34             // TODO Auto-generated method stub
35             System.out.println(this.toString());
36             
37             handler.postDelayed(this, 2000);
38         }
39     };
40 }

就不上效果图了。调用removeCallbacks()的时机是在一个activity退出的时候,一个类销毁的时候,这种情况都可以用onDestroy方法;再有就是可以在一个activity返回的时候,重写一下onKeyDown()方法,在里面remove。

以上就是我想记录下来的问题,还有一点,有个帖子提到了创建Message对象不能用new,而是要用Message.obtain()来创建,否则也会造成内存泄露。这一点我没验证过,不过官方的创建方法的确是obtain,没有用new的,这里也记录一下吧。

本人菜鸟,文笔和技术都还不过关,请多多指教~~~~~~~~ ^_^


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值