美文网首页
mac开发系列35:CPU监控

mac开发系列35:CPU监控

作者: 悲观患者 | 来源:发表于2017-08-14 14:59 被阅读277次

    今天有用户反馈,在mac微信不退出的情况下,盖上电脑,发热会比较厉害,然后打开电脑,用活动监视器看到mac微信的能耗和CPU占用率都比较高。很自然的想法就是,盖上电脑期间,mac微信究竟干了什么事情,这些事情当中,又有哪些比较耗CPU?

    如果是开着电脑,并且可以重现,就可以用instrument来定位耗CPU的业务代码。然而,盖上电脑没法用instrument,所以只能靠日志了。那么,日志要怎么加,才能让CPU占用率跟特定的业务代码关联起来呢?

    mach内核中有数据结构记录了每个线程的CPU占用率,而堆栈调用分析框架(这里选用BSBacktraceLogger)可以打出每个线程执行的现场日志,两者结合,就是我们想要的。下面直接上代码:

        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 nil;
        }
        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;    
        kr = task_threads(mach_task_self(), &thread_list, &thread_count); // 获取线程列表和线程数
        if (kr != KERN_SUCCESS) {
            return nil;
        }
    
        NSString* backstraces = nil;// 遍历每个线程    
        for (int j = 0; j < 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 nil;
            }
            basic_info_th = (thread_basic_info_t)thinfo; // 线程基本信息,包含CPU占用率、CPU占用时间等等
            if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
                float current_thread_cpu = basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0; // 当前线程的CPU占用率
                if(current_thread_cpu >= 自定义单核CPU占用率阈值){
        // 记录CPU占用率超过阈值的线程的执行堆栈
                    NSString* backstrace = [BSBacktraceLogger bs_backtraceOfMachThread:thread_list[j]];
                    backstraces = [NSString stringWithFormat:@"%@\n%@",     backstraces, backstrace];
                }
            }        
        }
    
        kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
    
        return backstraces;
    

    这里只是抛砖引玉,有待后续深入研究。

    相关文章

      网友评论

          本文标题:mac开发系列35:CPU监控

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