之前的文章从理论上介绍了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
一般大的内存泄漏直接观察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...
}
}
LeakCanary可以发现很细微的内存泄漏,具体到类文件,非常方便。
3.adb环境下输入以下命令
adb shell dumpsys meminfo [应用包名]
这个命令可以检查整个process进程的内存变化情况,不但可以检查虚拟机的内存,还可以检查native层的泄漏