美文网首页
卡顿优化

卡顿优化

作者: JammyT | 来源:发表于2018-03-06 01:05 被阅读19次

    发现卡顿点

    1. 使用instruments分析工具:

    可以找到耗时多的代码


    instruments

    2. 使用代码,添加FPS监控

    • 通过 CADisplayLink 获取屏幕FPS
    • 开子线程,定时监测页面FPS
    • FPS过低时,通过 CrashReporter 记录堆栈信息
    • 添加脚本,每次编译,获取dSYM文件,保存
    • 卡顿异常时,上报堆栈信息文件
    • 使用 symbolicatecrash 反堆栈解析,发现造成卡顿的代码
    获取页面FPS
    - (id)init {
        self = [super init];
        if( self ){
            _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick)];
            _displayLink.frameInterval = 2;
            [_displayLink setPaused:YES];
            // TODO 测试tracking状态下能否正常运行
            [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
        }
        return self;
    }
    
    - (void)displayLinkTick {
        _lastTickTimestamp = GYM_CURRENT_MS;
        if (_lastUpdateTimestamp <= 0) {
            _lastUpdateTimestamp = _displayLink.timestamp;
            return;
        }
        _historyCount += _displayLink.frameInterval;
        CFTimeInterval interval = _displayLink.timestamp - _lastUpdateTimestamp;
        if(interval >= 1) {
            _lastUpdateTimestamp = _displayLink.timestamp;
            _currentFPS = _historyCount / interval;
            _historyCount = 0;
            [self fpsUpdated:_currentFPS];
        }
    }
    

    3. 不止与FPS,还有CPU&内存使用情况

    获取CPU使用情况
    float cpu_usage() {
      kern_return_t kr;
      task_info_data_t tinfo;
      mach_msg_type_number_t task_info_count;
      
      task_info_count = TASK_INFO_MAX;
      kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
      if (kr != KERN_SUCCESS) {
        return -1;
      }
      
      task_basic_info_t      basic_info;
      thread_array_t         thread_list;
      mach_msg_type_number_t thread_count;
      
      thread_info_data_t     thinfo;
      mach_msg_type_number_t thread_info_count;
      
      thread_basic_info_t basic_info_th;
      uint32_t stat_thread = 0; // Mach threads
      
      basic_info = (task_basic_info_t)tinfo;
      
      // get threads in the task
      kr = task_threads(mach_task_self(), &thread_list, &thread_count);
      if (kr != KERN_SUCCESS) {
        return -1;
      }
      if (thread_count > 0)
        stat_thread += thread_count;
      
      long tot_sec = 0;
      long tot_usec = 0;
      float tot_cpu = 0;
      int j;
      
      for (j = 0; j < (int)thread_count; j++)
      {
        thread_info_count = THREAD_INFO_MAX;
        kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
                         (thread_info_t)thinfo, &thread_info_count);
        if (kr != KERN_SUCCESS) {
          return -1;
        }
        
        basic_info_th = (thread_basic_info_t)thinfo;
        
        if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
          tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
          tot_usec = tot_usec + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds;
          tot_cpu += basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
        }
        
      } // for each thread
      
      kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
      assert(kr == KERN_SUCCESS);
      
      return tot_cpu;
    }
    
    获取内存使用情况
    + (CGFloat)memoryUsage {
      struct mach_task_basic_info taskBasicInfo;
      mach_msg_type_number_t taskInfoCount = sizeof(taskBasicInfo) / sizeof(integer_t);
      if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&taskBasicInfo, &taskInfoCount) == KERN_SUCCESS) {
        return taskBasicInfo.resident_size / (1024 * 1024);
      }
      return 0;
    }
    

    引文

    github-GYMonitor

    相关文章

      网友评论

          本文标题:卡顿优化

          本文链接:https://www.haomeiwen.com/subject/spokfftx.html