移动App性能测评与优化1.5.2 一个类的内存消耗

1.5.2 一个类的内存消耗

首先,如果我们在代码中要使用一个类,例如以下代码:

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中<clinit>和<init>的代码。

2)分配dalvik-heap创建class对象实例。

在这个过程中,可能还会分配dalvik-bitmap和jit-code-cache内存。如果class Foo引用了其他类型,那就还需要先按照同样的逻辑创建被引用的class。由此可见,在创建一个类实例的每一步都需要消耗内存。我们接下来大概计算一下new操作需要消耗的内存。

根据Dalvik虚拟机的代码,能够得知class根据类成员和函数的数目分配LinearAlloc和aux-structure的多少,以及class本身及函数需要的字节数。我们再根据一个应用中所有class的总量进行平均计算,得到以下一组数据。

第一步是loadClass操作,加载类信息:

.dex mmap(class
def + class data): 载入一个类需要先读取259字节的mmap。

dalvik-LinearAlloc:
在LinearAlloc区域分配437字节,存放类静态数据。

dalvik-aux-structure:
在aux区域分配88字节,存放各种指针。

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

.dex mmap(code):为了执行类构造函数,还需要读取252字节的mmap。

dalvik-heap: 根据类的具体内容而变化。

可见在创建对象实例的操作中,Dalvik Other和.Dex Mmap部分就各需要约500字节的内存空间。但是考虑到4KB页面的问题,由于这些内存并不是连续分布的,所以可能需要分配多个4KB页面。当然由于很多类会在一起使用,使得实际的页面值不会那么多。

以我们举例的应用为例,总共有7042个类,启动后载入了1522个类,这时侯应用的.dex mmap内存消耗大约是5MB,平均后约为3.4KB。Dalvik Other的部分会少一些,但依然是远远超出需要使用的大小。

时间: 2024-09-19 17:01:12

移动App性能测评与优化1.5.2 一个类的内存消耗的相关文章

移动App性能测评与优化1.4.3 zygote共享内存机制

1.4.3 zygote共享内存机制 上一小节介绍了应用各部分内存的含义,读者对dumpsys meminfo输出的大部分数据都能够有所理解.但dumpsys meminfo工具还会输出Heap Size/Alloc/Free部分的数值.我们知道这些数值是Dalvik虚拟机统计的内存堆的使用量,但这些数值是如何对应到Pss内存上的?比如Heap Alloc和Heap Pss往往相差不远,那是不是可将其看做基本等同的呢?下面我们试图解释这几项数值之间的关系. 由于虚拟机运行时并不区分某个对象实例是

移动App性能测评与优化导读

前 言 Preface 写作背景 当前移动设备越来越多地涌现在我们日常生活中,像网络购物.充值缴费.新闻资讯.理财.团购.车辆保养等都可以通过移动设备来搞定.通过移动设备可以帮助人们更便捷高效地完成很多事,同时越来越多的需求也希望能通过移动设备来完成,这样也催生了很多工作机会,让IT技术人员能开发更多的App来满足不同用户的不同需求.相对于传统PC,移动设备有其自身的特点,如屏幕小.移动网络复杂且需要收费.电量有限等.因此,在完成用户一系列需求的背后,我们也面临一系列的问题.比如说,如何能保证开

移动App性能测评与优化1.4.2 smaps

1.4.2 smaps 由于Android底层基于Linux内核,进程内存信息也和Linux一致,所以Dalvik Heap之外的信息都能够从/proc/<pid>/smaps中取得. 在smaps中,列出了进程的各个内存区域,并根据分配的不同用途做标识,以下是root用户使用cat /proc/<pid>/smaps的一个例子: 788c2000-789bf000 rw-p 00000000 00:00 0          [stack:5113] Size:         

移动App性能测评与优化1.5.4 dex文件优化

1.5.4 dex文件优化 为了达到优化的目的,我们需要先了解dex文件的结构.dex文件结构如表1-2所示. 表1-2 dex文件结构 区 域  描 述  内 容 Header             索引区  String Id list 指向Data的偏移量         Type Id list             Method Prototype Id list             Field Id list              Method Id list      

移动App性能测评与优化1.5 案例:优化dex相关内存

1.5 案例:优化dex相关内存 上一节提到,随着代码功能的增加,代码复杂度也在不断地变大,这时我们往往会发现Dalvik Other和Dex Mmap这两部分消耗的内存也在不断增加.在之前的例子里,我们知道这两部分的内存已经接近总内存的一半.在Dalvik Heap已经充分优化的情况下,我们有必要继续研究这部分内存如何优化. 我们已经知道Dalvik Other存放的是类的数据结构及关系,而Dex Mmap是类函数的代码和常量.通常情况下,要减少这部分内存,需要从代码出发,精简无用代码,或者将

移动App性能测评与优化1.2.1 测试流程

1.2.1 测试流程 由于内存测试属于性能测试,Android系统又和Linux有很多相通之处,因此我们可以参考常见的Linux性能测试方法和指标,来制定客户端性能测试方案.常见的测试方法包括Monkey/UIAutomator类的常规压力测试.大数据/操作的峰值压力测试.长时间运行的稳定性测试等.这些方法都可以叠加在内存测试的方案中,观察这类场景下的应用内存情况,经常能够发现类似内存泄漏或OOM的问题. 参考了常见性能测试的方案,以及总结了以往对内存性能测试的经验后,我们总结出了一套进行内存测

移动App性能测评与优化1.4.1 从物理内存到应用

1.4.1 从物理内存到应用 我们首先要了解系统的内存机制,搞清楚物理内存是如何被分配到各个进程的,以及共享内存的机制,等等,理解这些机制对测试及优化都会有很大帮助. 根据Google提供的Android整体架构图,如图1-17所示,可以看到Android系统是基于Linux内核的,因此底层的内存分配及共享机制与Linux基本相同.但由于Android是为移动设备设计的,所以整套架构为了符合移动设备的特性,需要有较低的内存及能耗需求.因此Android只使用了Linux内核,不使用传统Linux

移动App性能测评与优化1.2.4 新的问题

1.2.4 新的问题 经过上一轮的优化,在内存监视器里新版本的Heap内存表现已经比较好了,新功能只消耗了几万字节到几十万字节内存.但是要注意的是,Heap内存并不是应用的全部,我们在设置或其他管理工具里看到的应用内存大小是应用整个进程的内存使用量.也有可能出现Heap部分完全没有增长而其他部分增长的情况. 要观察进程的内存使用情况,就需要用到其他的观测工具,Android里最常用于观察进程内存的方法就是dumpsys meminfo <package name|pid>命令. 对我们的新版应

移动App性能测评与优化1.4.4 多进程应用

1.4.4 多进程应用 根据上一节中的描述,当一个进程结束后,它所占用的共享库内存将会被其他仍然使用该共享库的进程所分担,共享库消耗的物理内存并不会减少.实际上,对于所有共享使用了这个库的应用,Pss内存都会有所增加.对于一般的进程,只是共享着zygote进程的Android框架等基础部分,而通常手机使用时的应用进程数达到几十个至上百个,所以某个进程结束后,其他进程内存增加的情况并不明显. 但对于多进程的应用来说,由于多个进程之间会共享很多内容,包括代码.资源.so库等,因此单个进程结束造成的影

移动App性能测评与优化2.1.2 软件测试

2.1.2 软件测试 上面一节讲述的都是从整机层面去量化并控制手机功耗,相比做App的公司来说做手机ROM的厂商较少.那么从应用的性能优化出发,上面讲述的硬件测试方法就不那么实用了,原因如下: 每个App本身的耗电是微量的,硬件测试方法中仪器本身波动可能无法体现App的功耗: 硬件测试方法只能通过测试整机功耗来体现App耗电,而这样很难避免其他App影响测试结果. 为了解决这个问题,MIG专项测试组从分析Android系统电量统计原理入手,并结合在实际项目中对耗电优化做的工作,来分享下对App功