in memory mergeChangesFromContextDidSaveNotification and saves the memory leak

advertisements

I has some increasing in memory size of my application (osx 10.8.3) when i'm using in memory type nsmanagedobjectcontext:

Bellow is a top 2 functions by instruments.

I do clearing of that in memory issues, but leak is still keep. Can u please suggest any way where i have to looking for?

here is a top responsible callers (all for CoreData):

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


Bcs Marcus don't write any example, i want to try to answer at my own question: Memory leaks gone as i see. But i got more pain, lets describe step by step.

After investigating around experience across internet resources i was choose scheme: I have two inMemory main MOCs with different persistent store coordinates.

  • Main MOC for dynamic info (NSMainQueueConcurrencyType)
  • Main MOC for static info (NSMainQueueConcurrencyType)

It's bcs i have very high load to first moc and not too much to second (but there is large data)

Then, all created threads create own MOCs (NSPrivateQueueConcurrencyType), make parent according type and do what they can do. It's multithread server, so i can delete object from another thread.

this is a code for save:

-(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 ;
        }

    }];
}

Model is worked correctly before on old scheme. When i starting using server in production, i got tonns of errors while save, where is talking that can't delete non-existing object (sub-objects from three). Looks like core data don't understand that objects have temporary ID and try to remove them in cascade mode.

I was thinking that too much error while save not good idea and i try to fix it by using obtainPermanentID: function. Errors go out, but i got crash report, which start time-to-time, described here:

core data child/parent save exception

Then, i was removed all obtainPermanentID's and return back to clear code. But now instead previous crashes got a crash:

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

Both crashes is going inside core data, and that mean that i can't do nothing with that. It's can't debugged by CORE_DATA_DEBUG bcs loading too high, and i can't @catch exception bcs it's inside apple libs, while they do execute requests). Apple bug report'ing doesn't answer for months. Here is two things which can be. First - i don't understand something in new model (maybe main MOCs must be in NSPrivateQueueConcurrencyType and child MOC must be in NSMainQueueConcurrencyType, or i need to save or merge something (but apple told that no), or i need to moving all issues of core objects like insert new objects fetch requests e.t.c inside ^performBlock of according MOCs e.t.c e.t.c e.t.c) . Second - new core data model is too buggy and i need move it out and do own model with objects.

Reasonable suggestions and experience sharing will be appreciated. I will adding more information while i will investigate all ways to avoid found bugs.

UPDATE

For now, good news for me (but probably not good for apple) Error was fixed by very strange reason. In my model i has that scheme: ActiveSession ----(to-one) ---> ActiveSessionIncomingLeg --(to-many)-> ActivePacket ----(to-one) ---> ActiveSessionOutgoingLeg --(to-many)-> ActivePacket The reason for using to-one relationship is i have only one leg incoming and outgoing. It worked fine before child/parent scheme and got me a easy access to attributes like:

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

Just to check, i was change to-one relationship to particular (to-many). And WOW - crash was done out. Hope it can helps to community. Happy coding.