问题背景:
3.8版本上线之后,QA在美团云测上对3.8版本进行深度性能测试时发现,3.8版本相比3.7版本、3.5版本,多数页面都有30M的内存增加,尤其是首页的五个tab。
问题分析及试错过程:
分析:
3.8版本相比3.7版本业务需求并不多。倒是升级了几个第三方库去除了项目中的retrolemabda表达式。
试错1:
我们暂定为是升级库的原因造成的,回退第三方库,打包上传云测,总是无法得到正确的内存变化曲线。当天我提交了十多次云测,只生成过一次测试报告,其他的都失败了。总之经历各种验证后发现与库的升级并无关系。
试错2:
认为是代码存在内存泄漏或大对象。使用Memory Monitor把相关页面都踩一遍,观察内存的变化,发现并无明显的内存泄漏和大对象分配的问题。抓取堆快照,使用MAT分析,发现资料库tab页面存在大对象分配,主要是资料库页面包含大量的图片,大图片占用的内存比较大。抓包发现运营给的图片都在100多k左右。认为是这个原因。修改图片请求走openApi(本地传递图片尺寸给服务端,服务端把客户端需要的图片返回来)。此外在页面销毁时增加如下代码:
/**
* 回收ImageView占用的图像内存;
* @param view
*/
public static void recycleImageView(View view){
if(view==null) return;
if(view instanceof ImageView){
Drawable drawable=((ImageView) view).getDrawable();
if(drawable instanceof BitmapDrawable){
Bitmap bmp = ((BitmapDrawable)drawable).getBitmap();
if (bmp != null && !bmp.isRecycled()){
((ImageView) view).setImageBitmap(null);
bmp.recycle();
bmp=null;
}
}
}
}
以上修改在美团云测下内存依然比3.7版本高30M。
试错3:
经过前面两次的试错,我们意识到我们忽略了一个重要的信息。应用初始进来内存就飙升了30M。我们把问题定位在:进入首页之前。同事说会不会是因为引导图的原因呢?初始进来的时候,引导图占用很大的内存,但是因为还没到达GC的临界点,所以每个页面都带着引导图的内存。
我心想,不会这么简单吧。但是我还是去排查了下,3.8版本增加了两张引导图,并且引导图放在xhdpi下,则一般手机占用的内存为:
>
3.8版本
第一张引导图:
xhdpi文件夹下:1190*1462
手机需要的是xxhdpi下的,所以会对xhdpi下的图片放大:1190*1.5*1462*1.5
最终内存占用大小:粗略计算 1190*1.5*1462*1.5*4 = 15.75M左右
第二张引导图内存占用大小:1109 × 1563*1.5*1.5*4=15.6M左右
3.7版本:引导图内存占用大小
882 × 1261*1.5*1.5*4=10M左右
3.8引导图内存占用大小比3.7大了21M左右
修改,上传云测,验证问题解决。