iOS 性能监测

 

卡顿监测:通过侦听主线程runloop事件方式(配合信号量)

#import "LagMonitor.h"

@interface LagMonitor()
@property(nonatomic,strong) dispatch_semaphore_t semaphore;
@property(nonatomic,assign) int                  timeoutCount;
@property(nonatomic,assign) CFRunLoopActivity    activity;

@end

@implementation LagMonitor{
    CFRunLoopObserverRef observer;
}

+(instancetype)getInstance{
    static dispatch_once_t onceToken;
    static LagMonitor * _lagMonitor;
    dispatch_once(&onceToken, ^{
        _lagMonitor = [[LagMonitor alloc] init];
    });
    return _lagMonitor;
};

-(void)startMonitor{
    if (observer) {
        return;
    }
    _semaphore = dispatch_semaphore_create(0);
    _timeoutCount = 0;
    CFRunLoopObserverContext context = {0,(__bridge void*)self,NULL,NULL};
    observer = CFRunLoopObserverCreate(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0,  &lagMonitorRunLoopObserverCallBack, &context);
    CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
    
    [self initChildThread];
}

-(void)stopMonitor{
    if(observer){
        CFRunLoopObserverInvalidate(observer);
        observer = NULL;
    }
}

static void lagMonitorRunLoopObserverCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info){
    
    LagMonitor * _monitor = (__bridge LagMonitor *)(info);
    _monitor.activity = activity;
    dispatch_semaphore_signal(_monitor.semaphore);
}

-(void)initChildThread{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        while (YES) {
            long result = dispatch_semaphore_wait(self.semaphore, dispatch_time(DISPATCH_TIME_NOW, 50*NSEC_PER_MSEC));
            if (result != 0) {
                if (self.activity==kCFRunLoopBeforeSources || self.activity==kCFRunLoopAfterWaiting) {
                    if (++self.timeoutCount < 5) {
                        continue;
                    }
                    NSLog(@"主线程卡顿了 .......");
                    dispatch_async(dispatch_get_global_queue(0, 0), ^{
                        //通过 PLCrashReporter 获取主线程的卡顿堆栈, 并进行记录或是择机上传
                        NSLog(@"记录卡顿 .......");
                    });
                }
            }
            self.timeoutCount = 0;
        }
    });
}
@end
View Code

卡顿监测:通过子线程ping主线程方式

 1 #import "Lag2Monitor.h"
 2 
 3 @interface Lag2Monitor()
 4 @property(nonatomic,assign) BOOL isLag;
 5 @property(nonatomic,assign) int timeCount;
 6 @property(nonatomic,strong) NSTimer * timer;
 7 @end
 8 
 9 @implementation Lag2Monitor
10 
11 +(instancetype)getInstance{
12     static dispatch_once_t onceToken;
13     static Lag2Monitor * _lagMonitor;
14     dispatch_once(&onceToken, ^{
15         _lagMonitor = [[Lag2Monitor alloc] init];
16     });
17     return _lagMonitor;
18 };
19 
20 -(void)startMonitor{
21     if (_timer) {
22         return;
23     }
24     _isLag = NO;
25     _timeCount = 0;
26     
27     dispatch_async(dispatch_get_global_queue(0, 0), ^{
28         [[NSThread currentThread] setName:@"Monitor_sub_thread"];
29         __weak Lag2Monitor * weakSelf = self;
30         self.timer = [NSTimer scheduledTimerWithTimeInterval:0.05 repeats:YES block:^(NSTimer * _Nonnull timer) {
31             if (!weakSelf.isLag) {
32                 weakSelf.timeCount ++;
33                 if (weakSelf.timeCount > 4) {
34                     NSLog(@"主线程卡顿了 .......");
35                     weakSelf.timeCount = 0;
36                     dispatch_async(dispatch_get_global_queue(0, 0), ^{
37                         //通过 PLCrashReporter 获取主线程的卡顿堆栈, 并进行记录或是择机上传
38                         NSLog(@"记录卡顿 .......");
39                     });
40                 }
41             }
42             dispatch_async(dispatch_get_main_queue(), ^{
43                 weakSelf.isLag = YES;
44                 weakSelf.timeCount = 0;
45             });
46         }];
47         [[NSRunLoop currentRunLoop] run];
48     });
49 }
50 
51 -(void)stopMonitor{
52     if(self.timer){
53         [self.timer invalidate];
54         self.timer = NULL;
55     }
56 }
57 
58 @end
View Code

 卡顿监测:通过CADisplayLink记录FPS

 1 #import "FPSMonitor.h"
 2 #import <UIKit/UIKit.h>
 3 @interface FPSMonitor ()
 4 
 5 @property(nonatomic,strong) CADisplayLink * displayLink;
 6 @property(nonatomic,assign) NSUInteger fpsCount;
 7 @property(nonatomic,assign) NSTimeInterval lastTimesmap;
 8 
 9 @end
10 
11 @implementation FPSMonitor
12 
13 +(instancetype)getInstance{
14     static dispatch_once_t onceToken;
15     static FPSMonitor * _fpsMonitor;
16     dispatch_once(&onceToken, ^{
17         _fpsMonitor = [[FPSMonitor alloc] init];
18     });
19     return _fpsMonitor;
20 };
21 
22 -(void)startMonitor{
23     if (_displayLink) {
24         return;
25     }
26     _fpsCount = 0;
27     _lastTimesmap = 0;
28     _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkSelector:)];
29     [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
30 }
31 
32 -(void)displayLinkSelector:(CADisplayLink *)sender{
33     _fpsCount ++;
34     if (_lastTimesmap==0) {
35         _lastTimesmap = sender.timestamp;
36         return;
37     }
38     if (sender.timestamp - _lastTimesmap >= 1) {
39         int fps = _fpsCount/(sender.timestamp - _lastTimesmap);
40         NSLog(@"displayCount FPS:%d",fps);
41         if (fps < 30) {
42             dispatch_async(dispatch_get_global_queue(0, 0), ^{
43                 //通过 PLCrashReporter 获取主线程的卡顿堆栈, 并进行记录或是择机上传
44                 NSLog(@"低于30FPS,记录卡顿 .......");
45             });
46         }
47         _fpsCount = 0;
48         _lastTimesmap = sender.timestamp;
49     }
50 }
51 
52 -(void)stopMonitor{
53     if(_displayLink){
54         [_displayLink invalidate];
55         _displayLink = NULL;
56     }
57 }
58 
59 @end
View Code

 

给些链接:

http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ%3D%3D&idx=1&mid=207890859&scene=23&sn=e98dd604cdb854e7a5808d2072c29162&srcid=0921FzoCw9j1W7n4uFYKuarC#rd

http://wereadteam.github.io/2016/12/12/Monitor/#more

http://www.tanhao.me/code/151113.html/

https://yq.aliyun.com/articles/10729

https://yq.aliyun.com/articles/17729?spm=5176.100239.blogcont10729.8.tfuWol

posted @ 2017-01-18 09:49  七夜i  阅读(192)  评论(0编辑  收藏  举报