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.
How big is this leak? How frequent? If the leak is inside of Core Data (as it appears) and it is small, there may be nothing you can do about it other than filing a radar.
I would suggest that you switch over to using the parent/child context design instead of using the NSManagedObjectContextDidSaveNotification as that is faster, doesn't block the main thread and probably will solve your memory leak to boot.
Update
300Mb in allocation is not a leak. Allocation is how much memory your application is using when it is running. If your leak is tiny (which it appears is the case) and it is inside of Core Data itself, there is nothing to be done about it as it is not worth chasing down.
Related
My app crashes on devices with 0.5GB memory. However, profiling memory usage in Xcode - it rarely goes above 140MB. I've used instruments to check leaks and there are none that are significant.
However, when I run my app, the memory used by 'Other Processes' is always very high. This is the resting state after launching:
I added a 1 second delay in each cycle of a loop in my code, and discovered that on each loop, the 'other processes' increases memory usage by about 3MB per object, until on 0.5GB devices, it runs out and crashes.
This question suggests that these are other apps using that memory, but I have closed every other app and the usage directly correlates with my looping code.
What could be using memory in other processes, that is actually running in my app? And why is my 'Other Processes' using up so much memory?
To give an idea of what I'm doing, I'm pulling data from Parse, then looping through each of the objects returned and creating an SKNode subclass object from the data. I add this node to an array, (for reference) and to the scene. Here's the code I'm doing on the main thread with the delay added. NB the line:
self drawRelationships:[_batches objectAtIndex:_index] forMini:_playerMini];
Is a BFTask and so asynchronous. And I'm dividing the array into smaller batches so I can see incremental memory usage, as each batch is drawn. If I try to draw the whole lot at once, OOM occurs immediately...
- (void)drawNewRelationships
{
_batches = [NSMutableArray array];
_index = 0;
[_playerMini fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) {
[ParseQuery getNewRelationshipsForMini:_playerMini current:_miniRows.relationshipIds withBlock:^(NSMutableArray *newRelationships) {
_batches = [self batchArrays:3 fromArray:newRelationships];
_index = 0;
[self drawBatches];
}];
}];
}
- (void)drawBatches
{
if ([_batches objectAtIndex:_index]) {
[self drawRelationships:[_batches objectAtIndex:_index] forMini:_playerMini];
_index++;
if (_index < [_batches count]) {
[self performSelector:#selector(drawBatches) withObject:nil afterDelay:1];
}
}
}
The node contains other data, (a couple of arrays, custom object) and I've tried running the app with all that data removed. I've tried running on the main thread and background threads. I've tried using BFTask to do things asynchronously. Everything I've tried ends up with the same behaviour - creating these SKNode objects eats up memory in 'Other Processes', until on low memory devices, it crashes.
It might be worth noting, that this behaviour has only started to occur since iOS9.
Basically, what can be using all this memory in 'other processes' and how can I free it?
Update
I've tried running the Sprite Kit sample app, and even that uses ~550MB in other processes when it launches. Could this be a major Sprite Kit bug?
Well it turned out to be a rather specific issue. The memory allocated to other processes was in fact memory leaking from my app. It occurred when I flattened a node with many children, but didn't nil an NSDictionary that contained references to all the pre-flattened nodes. For some reason, this mem leak didn't show up when profiling.
I also found a very good blog post: http://battleofbrothers.com/sirryan/memory-usage-in-sprite-kit on reducing your app's memory footprint. Worth a read if you're trying to optimise.
I want to provide a solution for those who are not necessarily using SpriteKit, but are facing issues with Other Processes taking up more and more memory - meaning there is a leak. This is the best way I've found to debug leaks in 'Other processes' so far.
Open Instruments, select Activity Monitor
Reproduce the steps in your application, see which process is taking ownership for the leak. For example if it is mediaserverd, you probably have a leak revolving around encoding/decoding or something media related, so things like releasing buffers or releasing the decompression session might not be working as planned.
Now that you have an idea of where to look, open Xcode and use the Debug Memory Graph tool, and look for the potential leaking instances, and you should see all the strong references towards it. For myself working a lot in objective-c++ it turns out to be missing autoreleasepools quite often.
I am developing an application on iOS8 based on reactive cocoa. The application mainly does network operations.
I noticed that when all my signals complete and all signal references are nulled, i see a few RAC* objects still alive in the memory when i checked through instruments. Is this intended or is my code leaking memory? When i run the signal, there is an activity surge where i see a lot of RAC objects getting allocated and then it falls back to this state as shown the the below screen capture.
Every subsequent invocation ends in this same state. So i am not very worried about it btw.
http://imgur.com/sCL8Y3p
Thanks,
Those are all shared global instances that RAC uses so it doesn't need to allocate memory for every use of them. I'm sure there's a fancier word for that optimization, but I can't think what it is. For example, check out RACUnit:
+ (RACUnit *)defaultUnit {
static dispatch_once_t onceToken;
static RACUnit *defaultUnit = nil;
dispatch_once(&onceToken, ^{
defaultUnit = [[self alloc] init];
});
return defaultUnit;
}
Since all RACUnits are the same, RAC never bothers to make more than one instance of it. That's all you're seeing.
I am stuck with the Cocoa Memory Managagment.
- (IBAction) createPush:(UIButton *)sender {
[create setEnabled:NO];
[release setEnabled:YES];
aLocation = [[Location alloc] init];
// Put some Example Stuff in the Class
aLocation.title = #"Apartment";
aLocation.street = #"Examplestreet 23";
aLocation.zip = #"12345";
aLocation.city = #"Exampletown";
aLocation.http = #"http://google.com";
aLocation.info = #"First Info Text";
aLocation.info2 = #"Second Info Text, not short as the first one";
aLocation.logoPath = #"http://google.de/nopic.jpg";
[aLocation.pictures addObject:#"http://google.de/nopic.jpg"];
[aLocation.pictures addObject:#"http://google.de/nopic.jpg"];
}
- (IBAction) releasePush:(UIButton *)sender {
[release setEnabled:NO];
[create setEnabled:YES];
[aLocation release];
aLocation = nil;
}
This Code works fine if I set or get Variables, but when I call the 'last' release (so the retain count is 0) it dealloc Method of aLocation gets called, but in Instruments Allocations you see that no memory is given back.
Here the Sources of Location:
http://homes.dnsalias.com/sof/Location.m
same Link with a '.h' instead of '.m' for the Header file (sorry its because of the Spaming Rule).
And the whole Project: http://homes.dnsalias.com/sof/Location.zip
Thanks for any help, where is my failure? Dennis
This Code works fine if I set or get
Variables, but when I call the 'last'
release (so the retain count is 0) it
dealloc Method of aLocation gets
called, but in Instruments Allocations
you see that no memory is given back.
What do you mean by "no memory is given back"?
Though oddly named, the memory management of aLocation is correct is the above code (assuming you have released it in dealloc as well).
Why doesn't memory use decrease when a single object is released?
(Paraphrased)
It is likely that your object is relatively tiny and, thus, that single deallocation falls below the ~20K or so needed to show up in Instruments.
If your app is crashing due to memory use issues, looking to a single deallocation is the wrong place to start. The first thing to do is to answer why your app is accreting memory and what is responsible for that growth.
Configure the Allocations instrument to only track live allocations. Then sort by total memory use. That'll show you what type of allocation is consuming the most memory. Start by reducing that.
Heapshot analysis can be very effective in these situations.
Additional Infos here because of maximum number of links and I have'nt the opportunity to post images...
What do you mean by "no memory is given back"?
I will show you the Instruments run, then it should be clear.
Screenshots from Instruments run
If want more Detail klick here for Instruments Run.
Your code is just fine. You are mistaken the output from Instruments. There is no Location object leaking.
For leaks, use the "Leaks" instrument. It won't fire. :-)
I've written a simple program in C and objC with a leak, and I cannot understand Leaks.
here it is:
int main(void)
{
int t = 78;
t = malloc(50);
t = 4;
return 0;
}
Can it show me which variable is the leak, or where it leaks?
Every Leaks tutorial on the internet (all two of them) are bad.
please help?
If you are testing the Leaks instrument with the code you provided, it is no wonder that it can't uncover any problems.
Leaks has a default snapshot interval of 10 seconds. But your program won't even run for 10s.
You are allocating in the scope of the application's entry point. "t" is valid (when not freed) until main exits. So the OS would reclaim the memory anyway.
And foremost: Your code does not contain a leak. It would be a leak if you "loose reference" to t. (e.g. by doing another t = malloc() or assigning t some other variable)
If you want to see Leaks in action, create a default Cocoa Application, add an instance variable "test" to your AppDelegate and put the following code into the implementation.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
test = malloc(50);
test = malloc(20);
}
I've not used Leaks, but there are plenty of tutorials on the net, starting with Apple's - Apple's developer documentation on the subject, Mobile Orchard and Cocoa is my Girlfriend, which seems to be the best.
I'm pulling and pushing data from an sqlite database. I use the FMDatabase cocoa wrapper.
I'm pulling and pushing data from multiple threads, but I made sure that more then one transactions never happen at the same time.
I get EXC_BAD_ACCESS after a few hundred call at the database but never at the same time. It's also not memory related (I've tried NSZombies and looked at the memory management of parameters).
Here is the stack and the code :
alt text http://grab.by/1VwY
FMResultSet* result = [db executeQuery:#"select latitude, longitude from cache where name = ?", name];
[result next];
NSString* latitude = [result stringForColumn:#"latitude"];
NSString* longitude = [result stringForColumn:#"longitude"];
I've got no idea, does somebody has one?
Looking through the relevant code in FMDatabase, it seems the sqlite_bind_text() routines uses the SQLITE_STATIC parameter to bind the result NSString's -UTF8String method (which returns an autoreleased pointer).
This means SQLite assumes that the text storage will remain valid for as long as the text remains bound, while the -UTF8String return is only valid for the current autorelease context. If you're using the same FMResultSet over multiple threads or function calls, changing that parameter to SQLITE_TRANSIENT would be much safer.
I'd suggest making that change in every sqlite3_bind_text() call and seeing if it still crashes. If that fixes it, you may want to report it back to the developer as a possible improvement.