更新2:我找到了一种解决方法,即同步MOC解除分配和保存。请参阅更新的项目。 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];
}
对于Core Data
,我们遵循thread-confinement
模式。对于每个线程,我们都有单独的managed object context
,并且上下文共享静态persistent store coordinator
。
编辑2:
更多信息:我发现当系统同时退出多个线程时会发生此问题。我们将托管对象上下文存储在线程字典中,并在线程退出时释放它们。
[[[NSThread currentThread] threadDictionary] setObject:dataManager forKey:@"IHDataManager"];
CPU使用率约为20%。
答案 0 :(得分:13)
我一直在经历这个问题。根据您的堆栈跟踪,我有一堆线程与_OSSpinLockLockSlow停滞。
它出现是一个活锁状态,自旋锁链接在一起。包括一些网络线程和核心数据。但正如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
中的新功能这不是一个真正的答案,更多的是我自己解决这个奇怪问题的日记,但也许你会觉得它很有用。
答案 1 :(得分:1)
如果问题仍然存在 - 这是iOS中的错误:OpenRadar crash report
此外,您可能会发现此博文有用:blog post
我认为您应该用其他东西替换OSSpinLocks以在您的应用中修复此问题。
我们在Unity3d游戏中遇到过这个错误。我们还没有在我们的应用程序中修复此问题,因为我们无法访问大多数本机iOS代码(我们使用C#编写游戏,并且我们使用了大量的第3方本机插件)。所以我不能向你推荐一些关于替换OSSpinLock的具体内容。抱歉我的英文。
<强>更新强>
许多Apple框架和库在内部使用OSSpinLock,因此您不需要明确地使用它来解决此问题。