dex2oat对应用启动性能的影响

不可忘记用爱心接待客旅,因为曾有接待客旅的,不知不觉就接待了天使。—希伯来书13:2

问题描述

chrome应用冷启动缓慢,跟参考机相比在luncher界面点击chrome图标,有一个明显的延迟,然后chrome才被启动起来。从点击图标到第一个界面加载完全显示,问题机相对参考机要慢3s左右。

初步分析

Android 平台侧性能优化之应用启动 一文里遇到过假冷启动引发的类似问题,按照这个思路检查排除了假冷启动的可能。
因为chrome都是通过play store跟新到最新版本v58.0.3029.83的。这也排除了chrome版本不同照成的因素。
参考机问题机的硬件参数有差异,问题机硬件是工程机的标准,而参考机是出货的硬件标准。这个可能存在影响,但直觉告诉我不应该有3s这么大的影响。

systrace分析

经过初步分析,该用systrace进一步深入分析。采用命令:

./run_systrace.py -a com.android.chrome gfx input view am app dalvik sched freq idle load -o trace.html

分别抓取参考机和问题机启动chrome的systrace。

问题机启动chrome systrace如下:
问题机systrace

参考机启动chrome systrace如下:
参考机systrace

注意以上获取的systrace图,高亮的部分bindApplication问题机相对参考机多耗时1s以上,这个是非常不合理的。
放大高亮的bindApplication区域:
bindApplication对比图

通过上图可以看到问题机OpenDexFilesFromOat方法把大部分时间都消耗在了打开base.apk,这个base.apk是未经过oat优化过的chrome apk,而参考机打开的是base.odex。怀疑问题机上系统对chrome未做oat优化。但oat优化是默认开启的啊,怎么在问题机上chrome没有生成对应的odex文件呢?

为了进一步确认问题,我们需要去/data/app/com.android.chrome-1目录下查看到底有没有odex文件生成。坑爹的是user版本没有root权限查看不了,只能去单独烧录一个eng版本的bootimg了。
烧录eng的boot获取root权限查看/data/app/com.android.chrome-1竟然有base.odex,这遇到了什么鬼。。。
再次抓取此时问题机的systrace查看。
烧录eng boot抓取systrace图

可以看到bindApplication由之前的1.888s变成现在的0.848s。已经靠近了参考机bindApplication花费的0.699s,如果再计算上eng boot对性能的影响,此时问题机bindApplication耗时应该很接近参考机了。

问题猜想

只是换了一个boot,不应该出现这种变化。有没有可能通过play store更新的chrome需要重启或者等待一段时间oat优化才会完成呢?因为更新完chrome后马上开始了问题分析,从之前的systrace看确实没有odex文件生成,而烧录eng boot后该odex文件就有了,eng boot应该不会影响odex文件的生成,烧录的过程重启了手机,重启过程很有可能左右该问题的主因。为了验证这个猜想,将参考机问题机的chrome都卸载更新的版本,重新通过play store 更新chrome,抓取systrace做对比参考。

结果发现参考机更新完成后直接测试没有出现OpenDexFilesFromOat耗时过长问题。
在看问题机同样也没有出现OpenDexFilesFromOat耗时过长问题。

卸载新版本,重新更新chrome,没有重启手机竟然没有出现启动异常。难道猜想错了,odex的生成压根与重启手机没有关系?这就有点费解了,跟预期的不一样啊,让人抓狂.


这里写图片描述

会不会是刚刷完机就复现问题,此时后台任务过多,导致chrome的oat操作没有完成呢?
会不会是JIT的问题呢?
会不会是虽然卸载掉了更新的apk,但某些地方还保留了记录,再次更新后,odex会自动生成呢?
在不成难道这是偶现问题?
满脑子的疑问飞过来,为了解决这些疑问,只有在刷机一次,从新做实验。

刷完机更新完chrome后,为防止偶现问题,多次抓取了冷启动的systrace,都复现问题。
二次确认

等待30分钟后,再次抓取systrace
等待30分钟后

看来不是后台任务过多,导致chrome的oat操作没有完成。
多次使用chrome,在抓取systrace分析。同样还是有问题,这里图就不贴了。看来也不是JIT的问题。
在看重启手机后的现象,启动时间终于正常了。
重启手机odex文件生成

终于找到了问题的表因,原来通过play store更新chrome应用,只有重启系统才会去做odex优化。而如果先卸载掉更新的chrome,在重新更新则没有问题。

刨根溯源

问题原因找到了,那这个问题是play store的问题还是说系统本身的问题,无法完全确认,但猜测很可能是系统本身的问题,google 不会留下这么明显的bug。因此还需要追溯没有做odex的原因。
odex的详细过程这里不展开讲述。后续在单独起一篇做总结。先给出主要的调用关系。


dex2oat调用关系图

沿着上图最终发现了问题所在。原来之前的同事在做开机优化时做了一个功能,将非重要应用的dex2oat操作放在了开机之后。可是没有考虑好更新应用时的逻辑处理,导致了问题的发生。本质原因找到了,那么该问题解起来就有方向了。这里涉及到具体的功能,不在赘述。

总结

程序员总爱给程序员挖坑,越向底层的改动越要小心,牵一发而动全身啊。
性能问题涉及的模块确实很多,许多问题总是那么的扑朔迷离,一定要有耐心去分析。
通过分析过程,我们也可以看到dex2oat对应用启动的性能确实提升巨大。systrace的好处就是能量化出这种性能差异。

				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
										if(!window.csdn.anonymousUserLimit.judgment()){
											window.csdn.anonymousUserLimit.Jumplogin();
											return false;
										}else if(!currentUserName){
											window.csdn.anonymousUserLimit.updata();
										}
									}
									
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值