应用程序坚持OSSpinLockLockSlow

Pet*_*hou 10 nsoperation ios xcode6.3 ios8.3

更新2:我找到了一种解决方法,即同步MOC解除分配和保存.请参阅更新的项目. https://github.com/shuningzhou/MOCDeadLock.git

注意:我更积极地失败了.不要在真实设备上运行它!

更新:演示此问题的示例项目. https://github.com/shuningzhou/MOCDeadLock.git

XCode 6.2:无法重现.

XCode 6.3:可重现.

XCode 6.4 beta:可重现.

========================== 问题 ====================== =========

我们的应用程序OSSpinLockLockSlow在升级到XCode 6.3后随机停留.在我们的项目中,我们使用NSOperationNSOperationQueue从服务器获取数据并使用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];
}
Run Code Online (Sandbox Code Playgroud)

因为Core Data,我们正在遵循这种thread-confinement模式.我们managed object context为每个线程分开,并且上下文共享一个静态persistent store coordinator.

编辑2:

更多信息:我发现当系统同时退出多个线程时会发生此问题.我们将托管对象上下文存储在线程字典中,并在线程退出时释放它们.

[[[NSThread currentThread] threadDictionary] setObject:dataManager forKey:@"IHDataManager"];
Run Code Online (Sandbox Code Playgroud)

CPU使用率约为20%. 在此输入图像描述 在此输入图像描述

fou*_*dry 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(),^{
         ...
         });
        });
Run Code Online (Sandbox Code Playgroud)

此代码段是某些网络/ JSON解析代码的一部分.'classForID'导致主线程上出现轻微的UI抖动,所以我对它进行了后台处理.

实际上,并发后台队列正在吐出一大堆短命的线程.这完全没必要.重构为单个串行队列修复了线程过度,从而摆脱了自旋锁问题.最后我意识到我根本不需要上课,所以这段代码已被驱除了.

问题已解决,但没有解释为什么这应该突然成为8.3的问题

我怀疑在这个问题中触及了同样的问题(尽管Cocoalumberjack在那里受到指责):
syscall_thread_switch iOS 8.3竞赛 - CocoaLumberjack错误?怎么调试这个?

..并在此Cocoalumberjack错误报告
https://github.com/CocoaLumberjack/CocoaLumberjack/issues/494

我也在使用CocoaLumberjack,但它没有任何问题线程中的功能,所以我认为这是一个红色的鲱鱼.潜在的原因似乎是创建过多的线程.

我已经在模拟器和设备上看到了问题,当它连接到XCode时,但我没有经历过独立于XCode运行时的问题.在iOS 8.3/XCode 6.3.1中对我来说是新的

这不是一个真正的答案,更多的是我自己解决这个奇怪问题的日记,但也许你会发现它很有用.