移动App性能测评与优化1.3.2 问题所在

简介:

1.3.2 问题所在

在了解DVM分配释放内存的机制后,根据dumpsys观察到的现象,猜测可能出现了页利用率问题(页内碎片)。如图1-13所示,第一行:在开始阶段,内存分配较满。第二行:经过GC(垃圾回收)后,大部分对象被释放,少部分留下来。

 

图1-13 产生内存碎片

这种情况下可能会产生的问题是,整页的4KB内存中可能只有一个小对象,但统计PrivateDirty/Pss时还是按4KB计算。

在通常的JVM中,借助Compacting GC机制,整理内存对象,将散布的内存移动到一起。但根据DVM的代码,DVM的Mark-Sweep算法不能移动对象,即没有内存整理功能,这种情况下就会形成内存空洞。

在猜测了可能的问题后,需要验证是否如猜测原因所致,由于MAT的对象实例数据中有地址和大小信息,我们先从MAT中导出数据。

在MAT中列出所有对象实例:list_objects java.*,然后选中所有数据并导出为csv格式,如下所示:

Class Name,Shallow Heap,Retained Heap,

class java.lang.Class @ 0x41fdd1e8,16,56,

class test.bxi$3 @ 0x432501c8,0,0,

class test.aaw$c$1 @ 0x4324fef8,0,0,

class test.ds @ 0x4324fc88,8,48,

class test.bxh @ 0x4324f438,8,248,

class test.bxg @ 0x4324f248,0,0,

class test.bxd$1 @ 0x4324f028,0,0,

处理导出的csv文件,按页面进行统计,取每个对象的地址的高位(&0xfffff000),结果相同的对象处在同一页面中。最后再按每个页面所有对象的大小分类统计,绘出直方图如图1-14所示。

 

图1-14 对页面利用率进行分类统计

这张图就是被测应用的页面利用率分布图,左边是利用率低的页面,右边是利用率高的页面。如果发现利用率低的页面数目增加,说明小对象碎片的数量增加了。

1.3.3 优化Dalvik内存碎片

为了能够找出有问题的代码,我们将上一步得到的数据继续处理。取出所有使用不满2KB的页面的内存块地址,再使用OQL将地址导入到MAT中,分析地址对应的对象是什么。图1-15所示就是将地址重新导入到MAT中得到的对象列表。

 

图1-15 内存碎片页中的对象

在这里基本就能看出来是哪些对象造成了内存的碎片化,数量比较多的前几类自然嫌疑比较大,可以先对前几个类的相关代码进行分析。也可以对这些代码进行针对性的内存测试,观察内存情况。

通过对生成这些对象的代码分析和模拟实验,我们还原出问题的基本过程:

生成对象的过程需要较多的临时变量。

批量生成过程中,由于还有空闲内存,虚拟机没有做垃圾回收。

完成后才进行垃圾回收,清除了所有的临时变量,留下碎片化的内存。

下面是造成这个问题的类似代码,执行这段代码将会在内存中形成很多碎片,造成很高的Pss占用:

private Object result[] = new Object[100];

void foo() {

  for(int i = 0; i < 100; ++i) {

    byte[] tmp = new byte[2000];

    result[i] = new byte[4];

  }

}

图1-16显示了类似情况下数组的分配范围,可见数组中每个成员的内存地址都是不连续的,并且相隔很远。这种情况下就会消耗很多个物理内存页面,增加Heap Free,造成例子中的问题。

 

图1-16 内存碎片对象地址的例子

经验总结

根据上述的流程,我们搞清楚了造成问题的原因,并且找到了问题代码。那么应当总结一些经验,以供借鉴。对于测试人员来说,有以下三个经验:

MAT是探索Java堆并发现问题的好帮手,能够迅速发现常见的图片和大数组等问题。但MAT也不是万能的,比如这个问题的数据就隐藏在对象的地址中。

对Android测试经验来说,可能容易找到的是应用代码及框架的各种测试经验和指导,底层以及涉及性能的测试经验并不太多。这方面可以借鉴Linux系统的测试经验,了解内核及进程相关的知识,熟悉常用工具。

内存分配的最小单位是页面,通常为4KB。

对于开发人员,以下两个经验也许能有帮助:

尽量不要在循环中创建很多临时变量。

可以将大型的循环拆散、分段或者按需执行。

相关文章
|
1月前
|
缓存 移动开发 JavaScript
如何优化UniApp开发的App的启动速度?
如何优化UniApp开发的App的启动速度?
435 139
|
1月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
210 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
2月前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
197 5
|
5月前
|
存储
《仿盒马》app开发技术分享--未完成订单列表展示逻辑优化(61)
上一节我们实现订单与优惠券的联合提交时,我去到订单列表页面查看生成的订单信息,发现现在的订单从信息展示到价格计算全都是有问题的。所以紧急的把对应的问题修改一下。
242 70
|
5月前
|
数据库
《仿盒马》app开发技术分享-- 优惠券逻辑优化(58)
我们已经实现了优惠券的领取和展示,现在已经趋近于一个完整的电商应用了,但是这时候问题又来了,我们领取完优惠券之后,我们的新用户优惠券模块依然存在,他并没有消失,既然我们是从云数据库中查询的数据,那么我们需要找到一个字段跟他对应起来,来实现新用户领券后关闭这个模块的展示,同时我们在未登录的时候他也要保持隐藏,登录后能实现优惠券的领取。然后在结算的时候得出有几张符合的券能用
117 9
|
5月前
《仿盒马》app开发技术分享-- 逻辑优化第三弹(83)
现在我们的app功能已经趋近完善,bug和缺失的细节也越来越少了,我们继续对app进行优化,首先是我们的积分页面,我们只实现了全部的积分展示内容,对收入和支出的积分明细并没有进行展示,这里我们要实现一下,然后就是我们的优惠券,我们已过期的优惠券并没有修改状态为已过期。
115 0
|
5月前
《仿盒马》app开发技术分享-- 个人中心页优化(62)
上一节我们实现了订单逻辑的优化,现在我们的app功能更加的完善了,并且随着我们的迭代逻辑疏漏越来越少,现在我们继续进行优化,在之前的业务逻辑中我们的个人中心页面展示了用户的余额以及积分商城入口,这里我们要展示余额准确的值,积分商城的入口我们修改为积分相关的功能入口。并且展示当前账号的积分余额
117 0
|
5月前
|
存储 安全
《仿盒马》app开发技术分享-- 购物车逻辑优化(39)
我们的app主要购物功能已经开发的相对来说比较完善了,接下来就针对各个功能的逻辑性进行迭代和修改,让我们的程序更加的健壮,减少一些逻辑上的bug
90 0
|
11月前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
824 4
|
传感器 iOS开发 UED
探索iOS生态系统:从App Store优化到用户体验提升
本文旨在深入探讨iOS生态系统的多个方面,特别是如何通过App Store优化(ASO)和改进用户体验来提升应用的市场表现。不同于常规摘要仅概述文章内容的方式,我们将直接进入主题,首先介绍ASO的重要性及其对开发者的意义;接着分析当前iOS平台上用户行为的变化趋势以及这些变化如何影响应用程序的设计思路;最后提出几点实用建议帮助开发者更好地适应市场环境,增强自身竞争力。