最后一部分是关于native heap,.dex,/dev/other的优化。
android的DDMS可以帮助查看c++ native heap的使用,但需要一定的配置,而且必须是root的手机。
在很多手机上,即使执行了这些命令,还是看不到结果。原因是很多手机上并没有安装debug版本的malloc库(包括libc_malloc_debug_leak.so 和 libc_malloc_debug_qemu.so)。这篇经常被引用的文章介绍了一种方法。是从供大家刷机用的CyanogenMod image中提取这两个文件,然后拷贝到自己的机器上。可以参考那片文章的具体步骤。
下面的问题是只能看到地址而不知道文件名和行号。至少有下面一些办法
自己用的是4.2版本的android。每次打开preference setting,/other/dev的private dirty都会增加很多(10M作用),并且不会释放。通过查看smaps,发现是/dev/pvrsrvkm导致的(4.3后设备名改为kgsl-3d0)。这个是显示相关的设备,按我的理解,大概是显存(如果没有独立显存,那是用于显示的内存)。通过网上查询,并不是只有我遇到这个问题。例如chrome也有这个问题。但还是不知道为何这个会增加。在一通乱试后,发现如果对activity设置android:hardwareAccelerated=false,就能解决。此时只增加shared dirty,并且关掉activity,内存会被释放。后来再查,看到stackoverflow上这篇文章,才知道这是4.2的一个bug。4.3和4.1都没有问题。
这个是java代码编译只会的.dex文件的大小。
开始自己使用eclipse编译出来的apk作性能分析,发现这个也有几M。但release版本的却不到1M。转念一想,原来是proguard的作用。proguard是android自带的混淆器,会对java的类名,函数名,变量名等重新命名,给一个非常短的名字。有两个作用,一个是使得反编译的代码不容易理解,另一个就是减少了dex文件的大小。经过这次内存分析,才发现其效果还是非常明显的。
因为proguard无法对res下的layout,xml文件做混淆,所以他们引用到的java类(例如一些view类)的名字是不能被改变的。所以一个小经验是让xml文件尽量少的引用java类,从而提高混淆的比例。
关于android内存优化,自己就先做了这些。整体思路就是从宏观到微观,利用各种工具和网络资料,从内存占用量最多的模块下手,一步步的分析原因,解决问题。再细化下去,还有很多代码级别的优化,例如perf tips里介绍了很多经验,memory efficient java也很值得参考。有时间再在这个级别做更多的优化。