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

[FAQ15597]whitelist: 针对个别apk由于的dex2oat原因安装失败/ 安装慢 / lunch慢的处理方法
2017-01-10
软件分支 L1.MP5L1.MP3L1.MP6L1.MP2...

内容

[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版本]
 
  1. 在PMS中修改
         在L和M版本不适用。
         N版本中经过层层调用,会调用到如下的函数,因此需要修改如下的文件:
 
private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
153            String[] targetInstructionSets, boolean checkProfiles, String targetCompilerFilter) {



在这函数中,可以判断传递下来的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(若上述方法无效):

1420      if (num_methods <= compiler_options_->GetNumDexMethodsThreshold()) {
1421        compiler_options_->SetCompilerFilter(CompilerOptions::kSpeed);
1422        VLOG(compiler) << "Below method threshold, compiling anyways";
1423      }
1424    }
1425
1426//mtk_add_begin
1427    static constexpr size_t kMinCompileDexSize = 4;
1428    if (!image_ && dex_files_.size() > kMinCompileDexSize) {
1429      compiler_options_->SetCompilerFilter(CompilerOptions::kInterpretOnly);
1430      LOG(INFO) << "Enable Whitelist Rules. Current Dex File Sizes:" << dex_files_.size();
1431    }
1432//mtk_add_end
1433
1434    return true;
1435  }
1436
1437  // Create and invoke the compiler driver. This will compile all the dex files.
1438  void Compile() {
1439    TimingLogger::ScopedTiming t("dex2oat Compile", timings_);
1440    compiler_phases_timings_.reset(new CumulativeLogger("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  优化 影响不大

 

  1. 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

 

  1. 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, 可以看到K35K35m16s

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

 

  1. 因此碰到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版本)中进行修改:

 

 

47static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
748    const char* output_file_name, int swap_fd, const char *pkgname, const char *instruction_set,
749    bool vm_safe_mode, bool debuggable)



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

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值