Android性能优化(bin启动优化)

    我们平时会在android里面写个bin程序来干点活,但是有时候我们会发现很奇怪的现象,我明明很早就启动这个bin了,但是过了很久bin程序的main函数才被调用~。这个是为啥呢?主要有2个原因:

一.bin程序依赖的so库太多,或者bin依赖的so库所依赖的so库非常多。典型的例子就是SystemServer中加载libandroid_servers.so的处理,一般都要消耗200ms左右(如果是x1的大核心跑,可能会快很多)。

二.bin程序中有很多全局变量或者静态变量,他们的初始化比较耗时。

我们这里暂时先介绍第二种类型。首先先上一个简单代码:

extern void doSayHello();

int main() {
  printf("main trace1 \n");
  doSayHello();
  return 0;
}

这里你会发现,执行bin以后过一段很久才会打印“main trace1”,从代码来看,打印log前没有耗时处理,我们看一下doSayhello()的代码:

#include <stdio.h>
#include "abc2.hpp"

void doSayHello() {
  printf("sayhello \n");
}

我们留意一下,doSayHello()上面有一个“abc2.hpp”的头文件,我们看一下这个头文件

class MyHeader {
public:
  MyHeader() {
    printf("myheader trace1 \n");
    usleep(1000*100);
    printf("myheader trace2 \n");
  }

  void say() {
    printf("myheader sayhello \n");
  }
};

MyHeader header;

好吧,我们发现这个头文件里面有一个全局变量header,它的构造函数非常耗时(我们用usleep来模拟耗时操作)。所以当你运行bin程序的时候,它在构造header这个全局变量的时候卡住了。我们再来看一下log,和我们的猜想差不多,哈哈。

 那接下来就该想个方法来优化了,怎么才能把这个耗时的全局成员变量初始化放到mian函数执行之后呢(如果能放到main函数之后执行,那就意味着多线程就能加载就能用起来了)?我们这个时候就需要用到dlopen/dlsym,运行时加载~~~,不在使用extern或者头文件方式引用接口函数。代码如下:

int main() {
  printf("main trace1 \n");
  //doSayHello();
  auto dlhandler = dlopen("./abc2.so",RTLD_GLOBAL | RTLD_NOW);
  if(dlhandler == nullptr) {
    printf("handler is nullptr \n");
  } else {
    printf("handler is not nullptr \n");
  }
  char *error = NULL;
  sayfunc func = (sayfunc)dlsym(dlhandler,"doSayHello");
  if(func == nullptr) {
    if ((error = dlerror()) != NULL)  {
         fprintf (stderr, "%s ", error);
         exit(1);
     }
  }
  printf("main trace1_1 \n");
  printf("func is %lx \n",func);
  func();
  printf("main trace2 \n");
  return 0;
}

这样的代码效果如下:

我们可以看到,全局变量的加载已经在main函数调用之后运行了。所以如果这个时候我们再使用一个多线程去做dlopen,是不是就能完美的优化整个bin的启动时间啦?啊哈哈。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值