https://github.com/shuningzhou/MOCDeadLock.git
注意:我更加积极地失败了.不要在真实的设备上运行它!
更新:演示此问题的示例项目.
https://github.com/shuningzhou/MOCDeadLock.git
XCode 6.2:无法复制.
XCode 6.3:可重现.
XCode 6.4 beta:可重现.
========================问题====================== =========
升级到XCode 6.3后,我们的应用程序随机停留在OSSpinLockLockSlow上.在我们的项目中,我们使用NSOperation和NSOperationQueue从服务器获取数据,并使用Core Data进行数据持久化.
这个问题从来没有发生过!您可以从堆栈跟踪中看到我们的代码没有调用.我不知道从哪里开始调试.有人可以提供一些指导吗?
先谢谢你!
请参阅堆栈跟踪
编辑:
我们正在使用AFNetworking,我们的NSOperations是AFHTTPRequestOperation的子类.我们添加了一些自定义属性并覆盖了方法 – (void)start:
- (void)start; { //unrelated code... NSString *completionQueueID = [NSString uuid]; const char *cString = [completionQueueID cStringUsingEncoding:NSASCIIStringEncoding]; self.completionQueue = dispatch_queue_create(cString,DISPATCH_QUEUE_SERIAL); //unrelated code.... [super start]; }
对于核心数据,我们遵循线程限制模式.我们对每个线程都有单独的托管对象上下文,上下文共享一个静态持久存储协调器.
编辑2:
更多信息:我发现当系统同时退出多个线程时,会发生此问题.我们将管理对象上下文存储在线程字典中,并且当线程退出时它们被释放.
[[[NSThread currentThread] threadDictionary] setObject:dataManager forKey:@"IHDataManager"];
cpu使用率约为20%.
解决方法
它似乎是一个活跃的情况,螺旋锁链在一起.包括一些网络线程和核心数据.但是正如Rob指出的那样,活动锁的症状应该包括高cpu使用率(螺旋锁不断旋转).在我的情况下(和您的情况)情况并非如此,cpu使用率低 – 模拟器的百分比使用率为20%,模拟器总体在活动监视器中为0.6% – 所以也许是一个死锁;-)
像你一样,我使用线程限制模式,每个线程独立的托管对象上下文,单个持久存储.
在您观察之后,挂起总是似乎遵循一大堆线程的处理,我检查了这种行为,可以确认是这样.
这让我想知道为什么我有这么多线程活跃.原来我正在使用具有并发后台队列的gcd:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0),^{ modelClass = [WNManagedObject classForID:mongoID]; dispatch_async(dispatch_get_main_queue(),^{ ... }); });
这个片段是一些网络/ JSON解析代码的一部分. ‘classForID’在主线程上引起轻微的UI抖动,所以我背景了.
实际上,并发后台队列正在吐出一大堆短命线程.这是完全不必要的.重构为单个串行队列,固定线程过多,从而摆脱了旋锁问题.最后我意识到我根本不需要上课,所以这段代码已经被驱逐了.
问题解决了,但是没有解释为什么这个突然变成8.3的问题
我怀疑在这个问题上遇到同样的问题(虽然Cocoalumberjack在那里被责备):
syscall_thread_switch iOS 8.3 race – CocoaLumberjack bug? how to debug this?
..在这个Cocoalumberjack错误报告
https://github.com/CocoaLumberjack/CocoaLumberjack/issues/494
我也在使用CocoaLumberjack,但是它不会在任何问题的线程中出现,所以我认为这是一个红色的鲱鱼.潜在的原因似乎是线程创建过多.
我已经在模拟器和设备上看到了这个问题,连接到XCode,但是我独立于XCode运行时没有经历过这个问题.在iOS 8.3 / XCode 6.3.1中我是新手