内存管理优化
- 原理:在大规模并发网络请求时,频繁创建和销毁网络请求对象等会导致内存频繁分配和释放,产生内存碎片,影响性能。优化内存管理旨在减少不必要的内存分配和释放,提高内存使用效率。
- 实现思路:
- 对象复用:
- 可以创建一个网络请求对象池,对于类似的网络请求(如相同域名、请求方法),复用已有的网络请求对象。在Objective-C中,可以使用
NSMutableArray
或NSCache
来实现对象池。例如:
@interface NetworkRequestPool : NSObject
@property (nonatomic, strong) NSMutableArray<NSURLSessionDataTask *> *taskPool;
+ (instancetype)sharedPool;
- (NSURLSessionDataTask *)getTask;
- (void)returnTask:(NSURLSessionDataTask *)task;
@end
@implementation NetworkRequestPool
+ (instancetype)sharedPool {
static NetworkRequestPool *pool = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
pool = [[NetworkRequestPool alloc] init];
pool.taskPool = [NSMutableArray array];
});
return pool;
}
- (NSURLSessionDataTask *)getTask {
if (self.taskPool.count > 0) {
NSURLSessionDataTask *task = self.taskPool.lastObject;
[self.taskPool removeLastObject];
return task;
}
return nil;
}
- (void)returnTask:(NSURLSessionDataTask *)task {
[self.taskPool addObject:task];
}
@end
- **自动释放池优化**:在处理大量并发网络请求时,合理使用自动释放池可以及时释放不再使用的对象。例如,在一个循环中发起多个网络请求,可以在循环内部创建自动释放池:
for (int i = 0; i < largeNumberOfRequests; i++) {
@autoreleasepool {
// 创建并发起网络请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"your-url"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 处理响应
}];
[task resume];
}
}
线程调度优化
- 原理:过多的并发请求会导致线程资源竞争,CPU上下文切换频繁,降低整体性能。合理的线程调度可以平衡线程数量,提高CPU利用率。
- 实现思路:
- 限制并发线程数:使用
NSOperationQueue
来控制并发请求的数量。NSOperationQueue
可以设置最大并发操作数,从而限制同时执行的网络请求数量。例如:
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
operationQueue.maxConcurrentOperationCount = 5; // 设置最大并发数为5
for (int i = 0; i < largeNumberOfRequests; i++) {
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
// 创建并发起网络请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"your-url"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 处理响应
}];
[task resume];
}];
[operationQueue addOperation:operation];
}
- **优先级调度**:对于一些重要的网络请求(如用户登录请求),可以设置较高的优先级。在`NSOperation`中,可以通过`queuePriority`属性来设置优先级。例如:
NSBlockOperation *highPriorityOperation = [NSBlockOperation blockOperationWithBlock:^{
// 高优先级网络请求操作
}];
highPriorityOperation.queuePriority = NSOperationQueuePriorityHigh;
[operationQueue addOperation:highPriorityOperation];
网络请求队列算法优化
- 原理:传统的先进先出队列在大规模并发场景下可能无法满足需求,需要更智能的队列算法来提高整体请求处理效率。
- 实现思路:
- 加权公平队列(WFQ):为不同类型的网络请求分配不同的权重,根据权重来决定请求处理的优先级。可以通过自定义一个网络请求队列类,内部维护一个字典来存储不同权重的请求队列。例如:
@interface WeightedFairQueue : NSObject
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSMutableArray<NSURLSessionDataTask *> *> *weightedQueues;
- (void)addTask:(NSURLSessionDataTask *)task withWeight:(NSInteger)weight;
- (NSURLSessionDataTask *)nextTask;
@end
@implementation WeightedFairQueue
- (instancetype)init {
self = [super init];
if (self) {
self.weightedQueues = [NSMutableDictionary dictionary];
}
return self;
}
- (void)addTask:(NSURLSessionDataTask *)task withWeight:(NSInteger)weight {
NSMutableArray *queue = self.weightedQueues[@(weight)];
if (!queue) {
queue = [NSMutableArray array];
self.weightedQueues[@(weight)] = queue;
}
[queue addObject:task];
}
- (NSURLSessionDataTask *)nextTask {
NSArray *weights = [self.weightedQueues allKeys];
NSArray *sortedWeights = [weights sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj1 compare:obj2];
}];
for (NSNumber *weight in sortedWeights) {
NSMutableArray *queue = self.weightedQueues[weight];
if (queue.count > 0) {
NSURLSessionDataTask *task = queue.firstObject;
[queue removeObject:task];
return task;
}
}
return nil;
}
@end
- **基于时间窗口的动态调整**:根据网络状况和服务器负载,动态调整请求队列的处理速度。例如,在一段时间内,如果网络响应时间较长,可以适当减少并发请求数量,反之则增加。可以通过定时器和网络状态监测来实现。
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) NSInteger concurrentCount;
- (void)startDynamicAdjustment {
self.concurrentCount = 5;
self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(adjustConcurrentCount) userInfo:nil repeats:YES];
}
- (void)adjustConcurrentCount {
// 获取网络状态,例如通过Reachability类
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus status = [reachability currentReachabilityStatus];
if (status == NotReachable) {
self.concurrentCount = 0;
} else if (status == ReachableViaWiFi) {
self.concurrentCount = 10;
} else if (status == ReachableViaWWAN) {
self.concurrentCount = 5;
}
// 调整NSOperationQueue的最大并发数
self.operationQueue.maxConcurrentOperationCount = self.concurrentCount;
}
网络状态监测优化
- 原理:更准确和高效的网络状态监测可以避免在网络不佳时发起过多请求,节省资源。
- 实现思路:
- 使用系统提供的网络监测:利用
Reachability
类(虽然官方推荐使用NWPathMonitor
,但Reachability
在Objective-C中使用广泛且成熟)来实时监测网络状态。例如:
Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
reachability.reachableBlock = ^(Reachability *reachability) {
// 网络可达,可适当增加并发请求数
};
reachability.unreachableBlock = ^(Reachability *reachability) {
// 网络不可达,暂停或减少并发请求
};
- **本地缓存状态**:为了减少频繁查询网络状态带来的开销,可以在本地缓存网络状态,并设置一个合理的过期时间。例如:
@property (nonatomic, assign) NetworkStatus cachedNetworkStatus;
@property (nonatomic, strong) NSDate *cacheExpirationDate;
- (NetworkStatus)getNetworkStatus {
if ([NSDate date].timeIntervalSince1970 < self.cacheExpirationDate.timeIntervalSince1970) {
return self.cachedNetworkStatus;
}
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus status = [reachability currentReachabilityStatus];
self.cachedNetworkStatus = status;
self.cacheExpirationDate = [NSDate dateWithTimeIntervalSinceNow:10]; // 缓存10秒
return status;
}