0

当我在内存类型 nsmanagedobjectcontext 中使用时,我的应用程序(osx 10.8.3)的内存大小有所增加:

波纹管是仪器的前 2 大功能。

我在内存问题中清除了它,但泄漏仍然存在。你能建议我在哪里寻找任何方法吗?

这是一个最负责任的调用者(全部用于CoreData):

CoreData    -[_NSFaultingMutableOrderedSet willRead] 
CoreData        _PFAllocateObject
CoreData        [NSDictionaryStoreMap _nodeFromObject:objectIDMap:]

在此处输入图像描述

在此处输入图像描述

4

2 回答 2

1

Bcs Marcus 没有写任何示例,我想尝试回答我自己的问题:正如我所见,内存泄漏消失了。但我得到了更多的痛苦,让我们一步一步描述。

在调查了互联网资源的经验后,我选择了方案:我有两个具有不同持久存储坐标的 inMemory 主 MOC。

  • 动态信息的主要 MOC (NSMainQueueConcurrencyType)
  • 静态信息的主要 MOC (NSMainQueueConcurrencyType)

这是 bcs,我对第一个 moc 的负载非常高,而对第二个 moc 的负载不是太多(但有大量数据)

然后,所有创建的线程创建自己的 MOC(NSPrivateQueueConcurrencyType),根据类型创建父级并做他们可以做的事情。它是多线程服务器,所以我可以从另一个线程中删除对象。

这是保存代码:

-(void) finalSaveMocInMemoryForDynamicInformation;
{
    [_mocInMemoryForDynamicInformation performBlock:^{
        @try {
            if ([_mocInMemoryForDynamicInformation hasChanges]) {
                NSError *error;
                AppDelegate *delegateMain = (AppDelegate *)[[NSApplication sharedApplication] delegate];
                if ([_mocInMemoryForDynamicInformation save:&error])
                {
                    [delegateMain.managedObjectContextInMemoryForDynamicInformation performBlock:^{
                        @try {
                            if ([delegateMain.managedObjectContextInMemoryForDynamicInformation hasChanges]) {
                                NSError *error;
                                if (![delegateMain.managedObjectContextInMemoryForDynamicInformation save:&error])
                                {
                                    [self logError:error forDelegate:delegateMain];
                                }
                            }
                        }
                        @catch (NSException *exception) {
                            NSLog(@"SIP CONTROLLER:ERROR:%@:%@ exception->%@ inside managedObjectContextInMemoryForDynamicInformation",[self class], NSStringFromSelector(_cmd),exception);
                            return ;
                        }

                    }];
                } else [self logError:error forDelegate:delegateMain];
            }
        }
        @catch (NSException *exception) {
            NSLog(@"SIP CONTROLLER:ERROR:%@:%@ exception->%@ inside _mocInMemoryForDynamicInformation",[self class], NSStringFromSelector(_cmd),exception);
            return ;
        }

    }];
}

模型之前在旧方案上正常工作。当我开始在生产中使用服务器时,我在保存时遇到了大量错误,其中说不能删除不存在的对象(三个中的子对象)。看起来核心数据不了解对象具有临时 ID,并尝试以级联模式将其删除。

我在想太多的错误,而保存不是一个好主意,我尝试使用 getPermanentID: 函数来修复它。错误消失了,但我得到了不时开始的崩溃报告,如下所述:

核心数据子/父保存异常

然后,我被删除了所有的获取永久 ID 并返回到清除代码。但是现在,以前的崩溃却发生了崩溃:

0   com.apple.CoreFoundation        0x00007fff867bcbd1 __CFBasicHashAddValue + 1297
1   com.apple.CoreFoundation        0x00007fff867c3268 CFBasicHashAddValue + 3176
2   com.apple.CoreFoundation        0x00007fff867d8ba9 CFSetAddValue + 121
3   com.apple.CoreData              0x00007fff89f15986 -[NSManagedObjectContext(_NSInternalAdditions) _insertObjectWithGlobalID:globalID:] + 182
4   com.apple.CoreData              0x00007fff89f15850 -[NSManagedObjectContext insertObject:] + 144
5   com.apple.CoreData              0x00007fff89eec056 -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] + 534
6   com.apple.CoreData              0x00007fff89f15722 +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] + 178
7   com.yourcompany.callsfreecalls  0x000000010b3a87f9 -[SipController packetForData:forSocketData:isUDPsocket:forIncomingLeg:] + 23545

Crashed Thread:  15  Dispatch queue: socketIncomingLegQueue

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0xfffffffffffffff8

VM Regions Near 0xfffffffffffffff8:
--> shared memory          00007fffffffe000-00007ffffffff000 [    4K] r-x/r-x SM=SHM  

两次崩溃都在核心数据内部,这意味着我对此无能为力。它不能通过 CORE_DATA_DEBUG bcs 加载太高来调试,我不能 @catch 异常 bcs 它在苹果库中,而它们确实执行请求)。Apple 错误报告几个月都没有答复。这里有两件事可以。首先 - 我不了解新模型中的某些内容(可能主 MOC 必须在 NSPrivateQueueConcurrencyType 中,子 MOC 必须在 NSMainQueueConcurrencyType 中,或者我需要保存或合并某些内容(但苹果告诉不),或者我需要移动所有问题的核心对象,如插入新对象、获取请求等在相应 MOC 的 ^performBlock 内等)。第二 - 新的核心数据模型太错误了,我需要将它移出并用对象做自己的模型。

合理的建议和经验分享将不胜感激。我将添加更多信息,同时我将调查所有避免发现错误的方法。

更新

现在,对我来说是个好消息(但对苹果来说可能不是好消息)错误被非常奇怪的原因修复了。在我的模型中,我有这样的方案: ActiveSession ----(to-one) ---> ActiveSessionIncomingLeg --(to-many)-> ActivePacket ----(to-one) ---> ActiveSessionOutgoingLeg --( to-many)-> ActivePacket 使用一对一关系的原因是我只有一条腿进出。它在子/父计划之前运行良好,让我可以轻松访问以下属性:

NSOrderedSet *set = incomingLeg.activeSession.activeSessionOutgoingLeg.activePacket;

只是为了检查,我改变了与特定(对多)的一对一关系。哇——崩溃了。希望对社区有所帮助。快乐编码。

于 2013-06-19T16:01:41.287 回答
0

这个泄漏有多大?多频繁?如果泄漏在 Core Data 内部(看起来)并且很小,那么除了提交雷达之外,您可能无能为力。

我建议您切换到使用父/子上下文设计而不是使用NSManagedObjectContextDidSaveNotification更快,不会阻塞主线程并且可能会解决您的内存泄漏问题。

更新

300Mb 的分配不是泄漏。分配是您的应用程序在运行时使用的内存量。如果您的泄漏很小(看起来就是这种情况)并且它在 Core Data 本身内部,则没有什么可做的,因为它不值得追查。

于 2013-06-03T15:47:39.170 回答