《移动App性能评测与优化》——内存篇总结

Android应用进程内存组成:

  • Dalvik虚拟机代码(共享内存)
  • 应用框架的代码(共享内存)
  • 应用框架的资源(共享内存)
  • 应用框架的so库(共享内存)
  • 应用的代码(私有内存)
  • 应用的资源(私有内存)
  • 应用的so库(私有内存)
  • 堆内存,其他部分(共享/私有)

Pss —— Proportional Set Size,表示进程实际使用的物理内存,是由私有内存加上按比例分担计算的各进程共享内存得到的值。

内存的主要组成索引

  • Native Heap:Native代码分配的内存,虚拟机和Android框架本身也会分配
  • Dalvik Heap:Java代码分配的对象
  • Dalvik Other:类的数据结构和索引
  • so mmap:Native代码和常量
  • dex mmap:Java代码和常量

Dalvik内存

Dalvik_Heap

包括dalvik-heap和dalvik-zygote。堆内存,所有的Java对象实例都放在这里。

LinearAlloc

包括dalvik-LinearAlloc。线性分配器,虚拟机存放载入类的函数信息,随着dex里的函数数量而增加。著名的65535个函数的限制就是从这里来的。

Accounting

包括dalvik-aux-structure、dalvik-bitmap、dalvikcard-table。这部分内存主要做标记和指针表使用。dalvik-aux-structure随着类及方法数目而增大,dalvik-bitmap随着dalvik-heap的增大而增大。

Code_Cache

包括dalvik-jit-code-cache。jit编译代码后的缓存,随着代码复杂度的增加变大。

Dalvik Heap内存常见问题:

随着功能的反复执行,Heap内存一直在持续增长。这种情况通常是出现了内存泄漏,这种情况最适合用LeakCanary等泄漏检查工具进行白盒测试分析

代码执行时出现了频繁的GC,Heap Alloc内存大幅度波动。这种情况通常是分配了许多临时变量或数组,随后又被迅回收,这种情况在确定具体场景后适合使用Heap Viewer/Allocation Tracker等工具来查看具体分配的对象

每次启动应用后,Heap内存相比以前版本稳定增长。这种情况通常出现在启动后待机或使用某功能后,可能是由新功能及代码改动引入的固定内存增长。这种情况适合获取Heap Dump后进行多版本或功能使用前后的对比,能够迅速找到增长原因。

Heap Alloc变化不大,但进程的Dalvik Heap Pss(Proportional Set Size)内存明显增加。这种情况比较少见,是由于分配了大量小对象造成的内存碎片

一个类的内存消耗

Foo f = new Foo();

第一步是loadClass操作,将类信息从dex文件加载进内存:

  1. 读取.dex mmap中class对应的数据。
  2. 分配native-heap和dalvik-heap内存创建class对象。
  3. 分配dalvik-LinearAlloc存放class数据。
  4. 分配dalvik-aux-structure存放class数据。

第二步是new instance操作,创建对象实例:

  1. 执行.dex mmap中的代码。
  2. 分配dalvik-heap创建class对象实例。

在这个过程中,可能还会分配dalvik-bitmap和jit-code-cache内存。如果class Foo引用了其他类型,那就还需要先按照同样的逻辑创建被引用的class。

内存碎片优化

内存分配的最小单位是页面,通常为4KB。但是由于DVM没有内存整理功能,可能一整页的内存被使用的只有很小一部分,但是计算私有内存还是按照整页 4KB 计算。
于是产生了很多内存碎片。

内存碎片产生过程:

  • 运行过程中生成很多临时变量。
  • 批量生成过程中, 由于还有空闲内存,虚拟机没有做垃圾回收。
  • 完成后进行垃圾回收, 清楚所有的临时变量,留下内存碎片。

内存碎片优化策略:

  • 尽量不要在循环中创建很多临时变量。
  • 可以将大型的循环拆散、分段或者按需执行。

Dalvik Other 优化

在优化内存时,不只有堆内存,还有其他许多类型的内存能够进行分析和优化。

dex文件有很多优化空间。在仔细统计并调整了dex文件的顺序后,往往能够节约1MB以上的mmap内存。

引入SDK库和调用新的系统API时需要考虑成本。有可能一些不常用的功能会导致大量的内存消耗。这时有可能需要多进程方案,将这些影响内存的操作放入临时进程执行。

你可能感兴趣的:(《移动App性能评测与优化》——内存篇总结)