Android App 内存泄漏检查工具MAT

移动开发 Android
Android App发生内存泄漏,常见的有Bitmap 使用后沒有recycle(),Drawable 使用后沒有setCallback(null)等。

Eclipse 有个插件工具MAT(Memory Analyzer Tool)可以帮助定位内存泄漏的对象。

  1. 安装MAT Update site: http://archive.eclipse.org/mat/1.1/update-site/
  2. 用DDMS工具Dump出问题App的.hprof文件 比如com.world.test2.hprof Dump之前最好先运行一下GC "Cause GC" , 确保dump出来的是还不能回收的对象等。
  3. 用SDK tools下工具hprof-conv.exe 做转换 hprof-conv com.world.test2.hprof appleak.hprof
  4. 用Eclipse “Open Head Dump”打开新转换的.hprof 文件--appleak.hprof 查看图形化界面,一个一个检查怀疑的点。

总结: MAT tool不会直接告诉你哪里内存泄漏,但是会列出怀疑的对象,需要你仔细检查这些对象为什么没有被释放掉。

下面是测试code, 在Android 4.2.2上测试过。 1. 此种情况可以引起Activity无法回收的情况,因为直接用类似private static Activity a0引用创建的Activity,导致Activity无法回收。 2. 此种情况没有引起Activity 无法回收的情况。 按理说这种情况应该也会导致静态Drawable 锁定Activity, 引用关系mBackground1-->Button-->Activity. 待分析

  1. public class MainActivity extends Activity implements Button.OnClickListener{   
  2.  
  3.     
  4.  
  5.  final private static String TAG = "MainActivity";   
  6.  
  7.     
  8.  
  9.  private static Drawable mBackground1;   
  10.  
  11.  private static Drawable mBackground2;   
  12.  
  13.  private static Drawable mBackground3;   
  14.  
  15.  private static Drawable mBackground4;   
  16.  
  17.      
  18.  
  19.  private static Activity  a0 ;   
  20.  
  21.  private static Activity  a1 ;   
  22.  
  23.  private static Activity  a2 ;   
  24.  
  25.  private static Activity  a3 ;   
  26.  
  27.  private static Activity  a4 ;   
  28.  
  29.      
  30.  
  31.    
  32.  
  33.  /*   
  34.  
  35.   * Shutdown intent   
  36.  
  37.  */  
  38.  
  39.  private final String INTENT_ACTION_REQUEST_SHUTDOWN =   
  40.  
  41.      "android.intent.action.ACTION_REQUEST_SHUTDOWN";   
  42.  
  43.      
  44.  
  45.  @Override  
  46.  
  47.  public void onCreate(Bundle savedInstanceState) {   
  48.  
  49.      Log.v(TAG, "onCreate  Activity="+this);   
  50.  
  51.     super.onCreate(savedInstanceState);   
  52.  
  53.      setContentView(R.layout.activity_main);   
  54.  
  55.      
  56.  
  57.      //1   
  58.  
  59.     if(false){   
  60.  
  61.      if(a0 == null){   
  62.  
  63.         a0 = this;   
  64.  
  65.         Log.v(TAG, "onCreate  Activity a0="+a0);   
  66.  
  67.      }   
  68.  
  69.      else if(a1 == null){   
  70.  
  71.         a1 = this;   
  72.  
  73.          Log.v(TAG, "onCreate  Activity a1="+a1);   
  74.  
  75.      }   
  76.  
  77.      else if(a2 == null){   
  78.  
  79.         a2 = this;   
  80.  
  81.          Log.v(TAG, "onCreate  Activity a2="+a2);   
  82.  
  83.      }   
  84.  
  85.      else if(a3 == null){   
  86.  
  87.          a3 = this;   
  88.  
  89.          Log.v(TAG, "onCreate  Activity a3="+a3);   
  90.  
  91.     }   
  92.  
  93.   else if(a4 == null){   
  94.  
  95.         a4 = this;   
  96.  
  97.         Log.v(TAG, "onCreate  Activity a4="+a4);   
  98.  
  99.      }   
  100.  
  101.      }   
  102.  
  103.     
  104.  
  105.     
  106.  
  107.     //set up button listener   
  108.  
  109.      Button myButton = (Button)findViewById(R.id.button_poweroff);   
  110.  
  111.     myButton.setOnClickListener(this);   
  112.  
  113.     
  114.  
  115.     
  116.  
  117.     myButton = (Button)findViewById(R.id.button_reboot);   
  118.  
  119.      myButton.setOnClickListener(this);   
  120.  
  121.      
  122.  
  123.      //2   
  124.  
  125.     if (mBackground1 == null) {     
  126.  
  127.         Log.v(TAG, "onCreate  mBackground1");   
  128.  
  129.          mBackground1 = getResources().getDrawable(R.drawable.adbroot_004);     
  130.  
  131.          myButton.setBackgroundDrawable(mBackground1);   
  132.     }   
  133.  
  134.     else if(mBackground2 == null){   
  135.  
  136.          Log.v(TAG, "onCreate  mBackground2");   
  137.  
  138.         mBackground2 = getResources().getDrawable(R.drawable.test002);   
  139.  
  140.         myButton.setBackgroundDrawable(mBackground2);   
  141.  
  142.     }   
  143.  
  144.      else if(mBackground3 == null){   
  145.  
  146.         Log.v(TAG, "onCreate  mBackground3");   
  147.  
  148.          mBackground3 = getResources().getDrawable(R.drawable.test003);   
  149.  
  150.          myButton.setBackgroundDrawable(mBackground3);   
  151.  
  152.     }   
  153.  
  154.     else if(mBackground4 == null){   
  155.  
  156.         Log.v(TAG, "onCreate  mBackground4");   
  157.  
  158.         mBackground4 = getResources().getDrawable(R.drawable.adbroot_003);   
  159.  
  160.          myButton.setBackgroundDrawable(mBackground4);   
  161.  
  162.      }   
  163.  
  164.     
  165.  
  166.    
  167.  
  168.   
  169.  
  170.  }  

 

责任编辑:张叶青 来源: 开源社区
相关推荐

2011-08-15 10:16:55

内存泄露

2011-08-19 14:27:29

iPhone开发

2013-12-17 15:46:04

iOS开发iOS 内存泄漏

2015-04-17 10:35:51

c++c++程序内存泄漏检测代码

2021-03-26 05:59:10

内存检测工具

2014-07-03 09:39:34

Java内存分析mat工具

2017-09-07 16:52:23

2016-03-21 10:31:25

Android内存泄露

2016-12-22 17:21:11

Android性能优化内存泄漏

2023-10-31 16:40:38

LeakCanary内存泄漏

2011-06-01 12:50:41

Android 内存

2014-07-30 14:22:41

AndroidWebView内存泄漏

2016-07-05 14:09:02

AndroidJAVA内存

2013-08-07 10:16:43

Android内存泄漏

2022-09-15 20:04:14

MemlabJavaScrip内存

2013-02-20 16:02:02

Android开发内存泄露

2024-03-11 08:22:40

Java内存泄漏

2023-12-18 10:45:23

内存泄漏计算机服务器

2012-02-22 21:28:58

内存泄漏

2017-12-18 17:21:56

AndroidJava内存泄漏
点赞
收藏

51CTO技术栈公众号