天天看点

Android高性能编码实战:修复内存泄漏

之前的文章从理论上介绍了Android高性能编码的几个优化的方向,下面我们从实战的角度讲述如何优化

Android高性能编码实战:App启动优化

Android高性能编码实战:网络框架优化

Android高性能编码实战:修复内存泄漏

        内存泄漏也称作“存储渗漏”,用动态储存分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。

移动设备内存稀缺珍贵,而Android分配给虚拟机的内存也有限,所以防止内存泄漏是性能优化的重点,内存泄漏在Android开发中主要发生在activity或者fragment生命周期结束时,该回收的内存没有回收。需要特别注意的有以下几个地方:

1.和activity生命周期有关的控件,比如handler、AsyncTask,以及需要activity context的控件

handler等控件需要进行异步操作,由于一般是内部类的原因,会持有外部环境的引用,也就是activity的引用,这个时候activity生命周期结束了,由于还存在引用,释放不掉,如果handler一直不释放,activity也就不会回收,造成内存泄漏。

2.超大图片、图片相关的缓存框架

超大图片,图片大小超过8M的大图片,需要进行压缩,ARGB8888改RGB565等操作之后使用,不然会直接造成OOM。

下载图片并生成bitmap,一定要做好缓存,释放bitmap和对应的ImageView,采用第三方图片缓存框架进行内存管理。

3.activity横竖屏切换、语言切换

横竖屏切换、语言切换等操作,activity会重新加载,

android:configChanges="keyboardHidden|orientation|screenSize"
           

在manifest activity标签中添加,可以防止activity重新创建。

下面介绍一个检查内存泄漏的工具

1.Android studio 自带monitors

Android高性能编码实战:修复内存泄漏

一般大的内存泄漏直接观察Allocated的大小就能发现

2.开源工具LeakCanary

LeakCanary是square的开源项目,定位内存泄漏神器,配置很简单

在gradle中配置

dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
   testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
 }      

在Application中配置

public class ExampleApplication extends Application {

  @Override public void onCreate() {
    super.onCreate();
    if (LeakCanary.isInAnalyzerProcess(this)) {
      // This process is dedicated to LeakCanary for heap analysis.
      // You should not init your app in this process.
      return;
    }
    LeakCanary.install(this);
    // Normal app init code...
  }
}      

然后操作你的APP,每个页面和功能都使用一遍,LeakCanary会自动检查内存泄漏,生成内存泄漏报告

Android高性能编码实战:修复内存泄漏

LeakCanary可以发现很细微的内存泄漏,具体到类文件,非常方便。

3.adb环境下输入以下命令

adb shell dumpsys meminfo [应用包名]

这个命令可以检查整个process进程的内存变化情况,不但可以检查虚拟机的内存,还可以检查native层的泄漏

Android高性能编码实战:修复内存泄漏