whitelist: 针对个别apk由于的dex2oat原因安装失败/ 安装慢 / lunch慢的处理方法

[DESCRIPTION]

自L版本之后,所有的APP要经过dex2oat处理过之后,才能运行。而dex2oat的任务是将原来的dex文件做预先的翻译,从而可以加快APP运行的时间。但是由于某些APP比较复杂,所以优化的时间就比较长。优化是以dex文件中的method为单位。dex2oat在优化时,会根据需要优化一定量的method。也就是说并不是优化的method都会被翻译成oat模式。根据优化的method的量的多少,可以分为如下的几种模式:



对APP的优化是通过dex2oat去执行的,而优化模式则是由于外界调用dex2oat通过参数的方式传递进去的,如果调用命令的时间没有传递参数那么,默认采用speed模式。

而调用dex2oat的路径一般有两种:安装APP的时候,由packagemanagerservice将参数传递给installd,由于installd调用dex2oat,也就是说优化模式由PMS决定。另外一种是APP自身优化插件,这时候,往往会指定为speed或者不指定。

前一种方式将APK的路径,优化之后的oat存放路径传递给dex2oat,但是由于内容可能发生改变,我们有可能无法在dex2oat对APP加以识别,所以,这时候,可以在installd或者pms中加以判断是否是我们认为为安装比较慢的APP,如果是的话,则想改变其优化的模式。

如果是后一种方式,往往会在优化之后的保存路径中携带APP的包名。


 目前有些apk像facebook、微信等apk,本身应用较大且code复杂度高,往往会出现安装失败,安装慢等问题。

安装失败是由于dex2oat进程编译时间过久打到了timeout,安装慢当然就是dex2oat做的compiler久的原因。

      还有像微信 这种在启动应用的时候是会优化插件的(而不是在安装的时候优化),这样就会导致应用lunch时间过久,给用户的感觉就是很晚才入。

说明:app 安装/ lunch时间的长短取决于CPU核心数,8核心的肯定是必4核心的优化要快,还取决于EMMC的性能 ,memory等系统因素。


目前解决安装慢或者启动慢主要从如下几个方面着手:

首先:保证系统方面已经没有可以优化的空间,例如,各种对应的patch已经合入,art是最新版本。如果已经没有优化空间,这时候,就需要考虑更改优化的模式以加快安装的时间,但是会降低app运行的性能。


1. 请先确保以下patch合入

L版本:

     patch: ALPS02522543(L1.MP9不需要合入)

               ALPS02861966(dependency 了所以重要的patch) 

M版本:

   ALPS02894769   


2. 发现:6735平台上dex2oat慢:demo 机 k35m 就比 k35 慢, 原因是CPU 频率影响,PS有说明, 参考以下FAQ尝试修改freq:

[FAQ17683]如何调整CPU corenum, freq, policy

[FAQ09538][CPU DVFS/Hotplug]运行时,把CPU固定在特定频率/特定核数的办法


更改dex2oat的模式:

如上面讨论那样,dex2oat发生的时机有两种情况:一是APP安装 ,二是APP自身优化插件。

更改优化模式的难点在于:如何识别进行优化的APP就是我们希望优化成指定模式的APP或得jar包。

目前在android中可以在三个地方进行判断 :

PackageManagerService当中,这个地方是安装APP必经之路

installd的commands.cpp当中,这也是安装APP的必经之路

dex2oat当中,dex2oat是所有APP或者jar包的必经之路,但是由于传递给dex2oat的参数有限,所以可能无法识别。

所以对于安装APP可以在pms当中修改,而对于jar包可以在dex2oat当中修改。

因为pms中我们可以知道APP的pkg信息,这个是每一个APP唯一的。

而对jar包来说,由于每一个APP在优化的时候,喜欢把优化之后的jar包放在自己安装的APP路径下面。所以,可以利用这个特性进行判断 。


[SOLUTION M版本]


在PMS中修改

在L和M版本不适用。

N版本中经过层层调用,会调用到如下的函数,因此需要修改如下的文件:

/frameworks/base/services/core/java/com/android/server/pm/PackageDexOptimizer.java


privateintperformDexOptLI(PackageParser.Packagepkg,String[]sharedLibraries,153String[]targetInstructionSets,booleancheckProfiles,StringtargetCompilerFilter) {

在这函数中,可以判断传递下来的pkg是否是我们需要的package,如果是的话,将targetCompilerFilter设置为speed-profile。

speed-profile会在安装的时候采用interperter-only,然后,运行一段时间之后,会将那些常用的方法优化成为speed模式。也就是说是有选择性的优化。

 2.修改

 L版本:

/art/dex2oat/dex2oat.cc

方法1:

// mtk add begin

if ((!oat_filename_.empty() && (oat_filename_.find("facebook") != std::string::npos))||(!zip_location_.empty() && (zip_location_.find("facebook") !=std::string::npos))||((!oat_location_.empty()) && oat_location_.find("facebook") != std::string::npos)){  // mtk modify 2016-06-06

                                    compiler_filter_string = "interpret-only";

                                    LOG(INFO) <<" This apk is in whitelist from property so set interpret-only ";

            }

// mtk add end

if (compiler_filter_string = nullptr){

      compiler_filter_string = "speed";

}

注意:CTS测项用的包不能使用interpret-only模式,因为一些CTS测项是性能相关的,如果改为interpret模式,会导致CTS不过。之前有客户为了追求更快的安装速度,将所有的包都改为interpret-only的,结果CTS就不过了,针对这种情况,可以把CTS的包再放到speed模式的白名单当中。cts的关键字为test.


方法2(若上述方法无效):

1420if(num_methods<=compiler_options_->GetNumDexMethodsThreshold()) {

1421compiler_options_->SetCompilerFilter(CompilerOptions::kSpeed);

1422VLOG(compiler) <<"Below method threshold, compiling anyways";

1423}

1424}

1425

1426//mtk_add_begin

1427staticconstexprsize_tkMinCompileDexSize=4;

1428if(!image_&&dex_files_.size() >kMinCompileDexSize) {

1429compiler_options_->SetCompilerFilter(CompilerOptions::kInterpretOnly);

1430LOG(INFO) <<"Enable Whitelist Rules. Current Dex File Sizes:"<<dex_files_.size();

1431}

1432//mtk_add_end

1433

1434returntrue;

1435}

1436

1437// Create and invoke the compiler driver. This will compile all the dex files.

1438voidCompile() {

1439TimingLogger::ScopedTimingt("dex2oat Compile",timings_);

1440compiler_phases_timings_.reset(newCumulativeLogger("compilation times"))


 [SOLUTION L版本]

在device.mk中加入PRODUCT_PROPERTY_OVERRIDES += ro.mtk.dex2oat_white_list=com.tencent.mm: (注意 包名后又冒号“:”

[添加source code](抱歉不能排版)

 /art/dex2oat/dex2oat.cc添加红色部分:


 #ifdef HAVE_ANDROID_OS

 extern "C"{

                  static int shouldUseInterpretonly(const char* filename){

                       char prop_buf[92];

                       memset(prop_buf,0,92);

                       bool have_whitelist = property_get("ro.mtk.dex2oat_white_list", prop_buf, NULL) > 0;

                       if(!have_whitelist)

                       return false;

                       char *str = prop_buf;

                       char appname[128],*ptrname = appname;

                       memset(appname,0,128);

                       while(*str)

{

         if(*str != ':'){

                                     *ptrname = *str;

                                      ptrname ++;

                                      str++;

              } else{

                                       str++;

                                      if(*appname != 0){

                                                   if(strstr(filename,appname)) //found

                                                     {

return 1; 

                                                      } else{

                                                              memset(appname,0,sizeof(appname));

                                                              ptrname = appname;

                                                      }

                                         }

                         }

}

return 0;

}

}

#endif

static int dex2oat(int argc, char** argv) {

          std::string dex_filename; //mtk_add

           ......

         if (option.starts_with("--dex-file=")) {

                    dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());

                    dex_filename = option.substr(strlen("--dex-file=")).data(); //mtk_add

         } else if......


if (compiler_filter_string == nullptr) { 

         if (instruction_set == kMips64) {

         // TODO: fix compiler for Mips64.

                     compiler_filter_string = "interpret-only";

         } else if (image) {

                     compiler_filter_string = "speed";

         } else {

                    #if ART_SMALL_MODE

                    compiler_filter_string = "interpret-only";

        #else

 #ifdef HAVE_ANDROID_OS

                 if(shouldUseInterpretonly(zip_location.c_str())){

                              compiler_filter_string = "interpret-only";

                              LOG(INFO) <<" This apk is in whitelist from property so set interpret-only";

                  }else if(shouldUseInterpretonly(dex_filename.c_str())){

                              compiler_filter_string = "interpret-only";

                              LOG(INFO) <<" This jar is in whitelist from property so set interpret-only";

                   }else{

 #endif

                               compiler_filter_string = "speed";

 #ifdef HAVE_ANDROID_OS

 #endif

#endif 

    }

}

CHECK(compiler_filter_string != nullptr);

.......

}






----------------------------------------------------------------------------------------------------------------------------------------------------

PS:新发现6735平台上dex2oat慢:demo 机 k35m 就比 k35 慢, 原因是CPU 频率影响, 与ART 优化影响不大


k35m M版本测试版本:

\\10.15.11.230\public1\ALPS_load\alps-mp-m0.mp1\alps-mp-m0.mp1-V2.23\k35mv1_64_op01_alps-mp-m0.mp1-V2.23_user

tencent.mm 版本V6.3.8.56_re6b2553

当时的CPU主频221000/ 988000KHz:

01-01 04:28:43.565 <7>[16560.006725]  (0)[56:cfinteractive][name:mt_cpufreq&][Power/cpufreq] @_mt_cpufreq_set_locked(): Vproc = 950mv, freq = 221000 KHz

01-01 04:28:44.366 <7>[16560.806949]  (0)[56:cfinteractive][name:mt_cpufreq&][Power/cpufreq] @_mt_cpufreq_set_locked(): Vproc = 1250mv, freq = 988000 KHz


M版本测试数据耗时install(34.077s)+launch(61.369ms+19.889s)=54s:

01-01 04:28:03.349302  1617  1661 I PackageManager.DexOptimizer: Running dexopt (dex2oat) on: /data/app/vmdl1857097406.tmp/base.apk pkg=com.tencent.mm isa=arm vmSafeMode=false debuggable=false oatDir = /data/app/vmdl1857097406.tmp/oat

01-01 04:28:03.471265  5654  5654 I dex2oat : Starting dex2oat.

01-01 04:28:37.548439  5654  5654 I dex2oat : dex2oat took 34.077s (threads: 4) arena alloc=23MB java alloc=14MB native alloc=88MB free=5MB 01-01 04:28:54.538837  5725  5725 I dex2oat : /system/bin/dex2oat --dex-file=/data/user/0/com.tencent.mm/app_dex/secondary-1.dex.jar --oat-file=/data/user/0/com.tencent.mm/app_cache/secondary-1.dex.dex

01-01 04:28:54.538837  5725  5725 I dex2oat : /system/bin/dex2oat --dex-file=/data/user/0/com.tencent.mm/app_dex/secondary-1.dex.jar --oat-file=/data/user/0/com.tencent.mm/app_cache/secondary-1.dex.dex

01-01 04:28:54.599338  5725  5725 I dex2oat : dex2oat took 61.369ms (threads: 4) arena alloc=3KB java alloc=20KB native alloc=921KB free=870KB

01-01 04:28:54.675067  5730  5730 I dex2oat : /system/bin/dex2oat --dex-file=/data/user/0/com.tencent.mm/app_dex/secondary-2.dex.jar --oat-file=/data/user/0/com.tencent.mm/app_cache/secondary-2.dex.dex

01-01 04:29:14.563627  5730  5730 I dex2oat : dex2oat took 19.889s (threads: 4) arena alloc=5MB java alloc=8MB native alloc=45MB free=4MB


k35 M版本测试版本:

\\10.15.11.230\public1\ALPS_load\alps-mp-m0.mp1\alps-mp-m0.mp1-V2.27\k35v1_64_op02_alps-mp-m0.mp1-V2.27_user

tencent.mm 版本V6.3.8.56_re6b2553

当时的CPU主频299000/1300000 KHz:

01-01 01:29:08.957 <7>[ 5573.215146]  (1)[57:cfinteractive][name:mt_cpufreq&][Power/cpufreq] @_mt_cpufreq_set_locked(): Vproc = 950mv, freq = 299000 KHz

01-01 01:29:08.967 <7>[ 5573.225164]  (1)[57:cfinteractive][name:mt_cpufreq&][Power/cpufreq] @_mt_cpufreq_set_locked(): Vproc = 1118mv, freq = 1300000 KHz


M版本测试数据耗时install(24.303s)+launch(45.461ms+13.574s)=38s, 可以看到K35比K35m快16s:

01-01 01:28:46.130507  2948  3018 I PackageManager.DexOptimizer: Running dexopt (dex2oat) on: /data/app/vmdl1834204165.tmp/base.apk pkg=com.tencent.mm isa=arm vmSafeMode=false debuggable=false oatDir = /data/app/vmdl1834204165.tmp/oat

01-01 01:28:46.215408  5590  5590 I dex2oat : Starting dex2oat.

0-01 01:29:10.519144  5590  5590 I dex2oat : dex2oat took 24.303s (threads: 4) arena alloc=22MB java alloc=14MB native alloc=88MB free=5MB

01-01 01:29:23.273697  5677  5677 I dex2oat : /system/bin/dex2oat --dex-file=/data/user/0/com.tencent.mm/app_dex/secondary-1.dex.jar --oat-file=/data/user/0/com.tencent.mm/app_cache/secondary-1.dex.dex

01-01 01:29:23.318485  5677  5677 I dex2oat : dex2oat took 45.461ms (threads: 4) arena alloc=3KB java alloc=20KB native alloc=921KB free=870KB

01-01 01:29:23.379928  5682  5682 I dex2oat : /system/bin/dex2oat --dex-file=/data/user/0/com.tencent.mm/app_dex/secondary-2.dex.jar --oat-file=/data/user/0/com.tencent.mm/app_cache/secondary-2.dex.dex

01:29:36.954313  5682  5682 I dex2oat : dex2oat took 13.574s (threads: 4) arena alloc=4MB java alloc=8MB native alloc=45MB free=4MB


因此碰到6735平台dex2oat慢,先判断是35m还是35, 再尝试修改CPU 频率测试


[FAQ17683]如何调整CPU corenum, freq, policy

[FAQ09538][CPU DVFS/Hotplug]运行时,把CPU固定在特定频率/特定核数的办法

M版本:

由于APK安装时传递下来的APK路径不包含PKG信息无法生效,但是对于一些jar包,可以判断oat保存的路径,因为往往会在路径中透露pkg的信息。可以利用此判断是否是我们关注的jar包在优化插件。

如下的Log所示:

01-01 08:34:27.063 I/dex2oat ( 7714): /system/bin/dex2oat --runtime-arg -classpath --runtime-arg --instruction-set=arm --instruction-set-features=default --runtime-arg -Xrelocate --boot-image=/system/framework/boot.art --dex-file=/data/data/com.tencent.mm/app_dex/secondary-2.dex.jar --oat-fd=62 --oat-location=/data/data/com.tencent.mm/app_cache/secondary-2.dex.dex --runtime-arg -Xms64m --runtime-arg -Xmx512m

--dex-file,--oat-location都透露了pkg的信息。

因此,可以判断这两个参数是否包含了我们的要求的pkg信息,如果有的话,可以设置

compiler_filter_string为interpreter-only


N版本上面,也是判断上面的参数,这后,满足条件之后,可以想办法调用

compiler_options_->SetCompilerFilter(kSpaceProfile);

 对于L和M版本中如果是安装APP可以在commands.cpp或者commands.c(L版本)中进行修改:



47staticvoidrun_dex2oat(intzip_fd,intoat_fd,constchar*input_file_name,748constchar*output_file_name,intswap_fd,constchar*pkgname,constchar*instruction_set,749boolvm_safe_mode,booldebuggable)

中判断pkg name然后,设置:have_dex2oat_compiler_filter_flag的值为interpreter-only

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358