原文:http://www.cnblogs.com/zdwillie/p/3287150.html

最后一部分是关于native heap,.dex,/dev/other的优化。

Native Heap分析和优化

android的DDMS可以帮助查看c++ native heap的使用,但需要一定的配置,而且必须是root的手机。

  1. 在~/.android/ddms.cfg增加"native=true"。这样子ddms才会有native heap的tab。
  2. 指向下面adb命令打开malloc的debug模式
    adb root
    adb shell setprop libc.debug.malloc 1
    adb shell stop
    adb shell start
  3. 打开standalone的DDMS(不是eclipse中那个,是独立的应用程序,sdk目录下有),然后在native heap这个tab下,可以查看native heap的分配情况。

在很多手机上,即使执行了这些命令,还是看不到结果。原因是很多手机上并没有安装debug版本的malloc库(包括libc_malloc_debug_leak.so和libc_malloc_debug_qemu.so)。这篇经常被引用的文章介绍了一种方法。是从供大家刷机用的CyanogenModimage中提取这两个文件,然后拷贝到自己的机器上。可以参考那片文章的具体步骤。

下面的问题是只能看到地址而不知道文件名和行号。至少有下面一些办法

  1. 使用ndk中的arm-linux-androideabi-gdb(android ndk的gdb)来打开.so文件。这里的.so不能使apk中使用的,因为那个已经把symbol给strip了。而应该使用***\obj\local\armeabi\***.so,这个是带着symbol的。
    然后可以在gdb中使用info symbol 0x000xxxxx来定位到地址对应的函数名。这里的0x000xxxxx是ddms中地址把前三位变成0。因为gdb .so中使用.so的静态地址,而ddms中的地址经过动态链接,是内存的虚拟地址。但动态链接并不改变地址的后五位,所以这里后五位保持不变,前三位变成0,从而转换为so的静态地址。
    然后用info line xxx.cpp:xxx来定位具体行。
    这个方法比较繁琐,因为当时自己没找到好办法,就这么用的。
  2. 用ndk的arm-linux-androideabi-addr2line。后面跟so和0x000xxxxx。跟gdb差不多,会简单一些。
  3. 有人说设置PATH加上包含addr2line的目录,然后再设置ANDROID_PRODUCT_OUT可以在ddms中直接显示函数名和行号,但没有试过。

/other/dev分析和优化

自己用的是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都没有问题。

.Dex mmaps优化

这个是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也很值得参考。有时间再在这个级别做更多的优化。

更多相关文章

  1. 使用valgrind检测Android(安卓)native程序的内存
  2. Android资源类型、结构、使用
  3. Android中自定义属性的格式详解
  4. context对于android的重要意义
  5. Android(安卓)Studio 简单介绍和使用问题小结
  6. Android(安卓)7.0新特性
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. 懒加载fragment基类
  2. life cycle of an Android(安卓)activity
  3. ShareSDK Android常见问题汇总
  4. Android(安卓)studio button 按钮 四种绑
  5. android音视频采集参考
  6. Android与HTML5交互模版
  7. Dalvik opcodes 【转过来 备份】
  8. Android(安卓)Bluetooth Stack: Bluedroi
  9. 安卓加载网页
  10. Android(安卓)recyclerview 支持网格布局