OSX/ObjectiveC: List all the objects created in the heap by my app - objective-c

Is it possible to list all the objects that lives in the heap and have been created by my app?
I think it's possible, Instruments do something like this.

Instruments
In instruments, choose the Allocations template in the Memory system and you'll have the ability to look at all objects that are either live in the heap, or which have ever been allocated in the heap.
There's reasonably good filtering in here as well, and if you have lots of memory, or an app that doesn't create/destroy a lot of objects, you can even track reference counts.
Code
There isn't an API to look into the malloc/free data structures officially, so if you have a compelling non-debugging need to look at individual allocs, you're probably looking at replacing the standard memory allocation routines with a specialized instrumented version (kind of like what guard malloc does -Guard Malloc).

Related

Memory not fully freed

I just started creating an app using SceneKit and SpriteKit and ARC for the first time. I noticed that the memory usage is quickly increasing when I switch between different Views. My first thought was that I have memory leaks but I am not sure now. The behavior even occurs in this basic example:
for(int r=0;r<9999999;r+=1){
NSString *s=[NSString stringWithFormat:#"test%i",r];
s=nil;
}
From my understanding an NSString Object is created and directly released in this loop. I've tried this example in the iPhone-Simulator and on an iPhone and it makes the app use several hundreds MB of RAM after this loop is executed. (I am checking the memory usage with the Xcode debug navigator)
I am obviously misunderstanding something. Why is this example still retaining memory afterwards?
edit:
You could also create a new project: iOS -> Game -> Game Technology: SceneKit
Then add this into viewDidLoad:
for(int r=0;r<999999;r+=1){
SCNNode *tn=[SCNNode node];
tn=nil;
}
The memory will peak at 550MB and go down to 300MB which would be to much if there objects were fully released and removed from the RAM.
Don't rely on NSString for memory diagnostics. It has fairly atypical behavior.
This is a not-uncommon scenario, one that I've seen on S.O. more than once, that in an attempt to reduce some complicated memory problem to something simpler, the developer creates a simplified example using NSString, unaware that choosing that particular class introduces curious, unrelated behaviors. The new "Debug Memory Graph" tool or the old tried-and-true Instruments (discussed below) is the best way to diagnose the underlying issues in one's code.
As an aside, you talk about releasing objects immediately. If your method doesn't start with alloc, new, copy or mutableCopy, the object returned will not deallocated immediately after falling out of scope, because they're autorelease objects. They're not released until the autorelease pool is drained (e.g., you yield back to the run loop).
So, if your app's "high water" mark is too high, but memory eventually falls back to acceptable levels, then consider the choice of autorelease objects (and/or the introducing of your own autorelease pools). But generally this autorelease vs non-autorelease object distinction is somewhat academic unless you have a very long running loop in which you're allocating many objects prior to yielding back to the run loop.
In short, autorelease objects don't affect whether objects are deallocated or not, but merely when they are deallocated. I only mention this in response to the large for loop and the contention that objects should be deallocated immediately. The precise timing of the deallocation is impacted by the presence of autorelease objects.
Regarding your rapid memory increase in your app, it's likely to be completely unrelated to your example here. The way to diagnose this is to use Instruments (as described in WWDC 2013 Fixing Memory Issues). In short, choose "Product" - "Profile" and choose the "Leaks" tool (which will grab the essential "Allocations" tool, as well), exercise the app, and then look at precisely what was allocated and not released.
Also, Xcode 8's "Debug Object Graph" tool is incredibly useful, too, and is even easier to use. It is described in WWDC 2016's Visual Debugging with Xcode. With this tool you can see a list of objects in the left panel, and when you choose one, you can see the object graph associated with that object, so you can diagnose what unresolved references you might still have:
By the way, you might try simulating a memory warning. Cocoa objects do all sorts of caching, some of which is purged when there's memory pressure.
If you turned on any memory debugging options (e.g., zombies) on your scheme, be aware that those cause additional memory growth as it captures the associated debugging information. You might want to turn off any debugging options before analyzing leaked, abandoned or cached memory.
Bottom line, if you're seeing growth of a couple of kb per iteration and none of the objects that you instantiate are showing up and you don't have any debugging options turned on, then you might not need to worry about it. Many Cocoa objects are doing sundry cacheing that is outside of our control and it's usually negligible. But if memory is growing by mb or gb every iteration (and don't worry about the first iteration, but only subsequent ones), then that's something you really need to look at carefully.

What does "live in the heap" mean?

I'm learning Objectiv C, and I hear the term "live in the heap" constantly, from what I understand its some kind of unknown area that a pointer lives in, but trying to really put head around the exact term...like "we should make our property strong so it won't live in the heap. He said that since the property is private. I know it'ss a big difference It's pretty clear that we want to make sure that we want to count the reference to this object so the autorelease wont clean it (we want to "retain" it from what i know so far), but I want to make sure I understand the term since it's being use pretty often.
Appreciate it
There are three major memory areas used by C (and by extension, Objective C) programs for storing the data:
The static area
The automatic area (also known as "the stack"), and
The dynamic area (also known as "the heap").
When you allocate objects by sending their class a new or alloc message, the resultant object is allocated in the dynamic storage area, so the object is said to live in the heap. All Objective-C objects are like that (although the pointers that reference these objects may be in any of the three memory data areas). In contrast, primitive local variables and arrays "live" on the stack, while global primitive variables and arrays live in the static data storage.
Only the heap objects are reference counted, although you can allocate memory from the heap using malloc/calloc/realloc, in which case the allocation would not be reference-counted: your code would be responsible for deciding when to free the allocated dynamic memory.

CoreData and NSManagedObject memory state

this a question I always wanted to ask.
When I am running an iOS application in Profiler looking for allocation issues, I found out that NSManagedObject stays in memory long after they have been used and displayed, and the UIViewController who recall has been deallocated. Of course when the UIViewController is allocated again, the number is not increasing, suggesting that there's no leak, and there's some kind of object reuse by CoreData.
If I have a MyManagedObject class which has been given 'mobjc' as name, then in profiler I can see an increasing number of:
MyManagedObject_mobjc_
the number may vary, and for small amount of data, for example 100 objects in sqllite, it grows to that limit and stays there.
But it also seems that sometimes during the application lifecycle the objects are deallocated, so I suppose that CoreData itself is doing some kind of memory optimizations.
It also seems that not the whole object is retained, but rather the 'fault' of it (please forgive my english :-) ) because of the small live byte size.
Even tough a lot of fault objects would also occupy memory.
But at this point I would like some confirmation:
is CoreData really managing and optimizing object in memory ?
is there anything I can do for helping my application to retain less object as possible ?
related to the point above, do I really need to take care of this issue or not ?
do you have some link, possibly by Apple, where this specific subject is explained ?
maybe it is relevant, the app I used for testing rely on ARC and iOS 5.1.
thanks
In this SO topic, Core Data Memory Management, you can find the info you are looking for.
This, instead, is the link to Apple doc on Core Data Memory Managament.
Few tips here.
First, when you deal with Core Data you deal with an object graph. To reduce memory consumption (to prune your graph) you can do a reset on the context you are using or turn objects into fauts passing NO to refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag method. If you pass NO to that method, you can lose unsaved changes, so pay attention to it.
Furthermore, don't use Undo Management if you don't need it. It increases memory use (by default in iOS, no undo manager is created).
Hope that helps.

Problems with memory management, autorelease, permanent heap is sometimes 250+ kb on iOS

I'm really pulling my hair out on this one, it seems that I'm having severe issues with memory management on an iOS app.
Here's the case: first I load table. When the user taps a cell, it presents a complicated view. The most memory consuming about the view is that it's loading 20+ UIImages of 500x500. There are two other tabs in that view, loading a list of media (those UIImages, but then in a table) and another simple table.
When I return back to the first table view, apparently over 250 kB is still allocated on heap. I know the view is complicated, but there's no reason to keep so much memory alive. And well, guess what, when I do switch to the view a lot, eventually the app runs out of memory and gets killed.
What I tried to solve it:
Fix all Analyze issues, so according to that there are no leaks anymore.
Check all inits again for releasing, making use of autorelease where possible.
Checking all the memory leaks using Instruments -> Leaks. In a runtime of 6, I get not more than 2 or 3 leaks.
Last, Instruments -> Allocation, checking the heap. This is what bothers me, between two marked heapshots I get a difference of 250+ kB. I've looked into it, using the detailed views. I can't get my head around it: when it's pointing to one of my methods/classes, I'm pretty sure everything in there is either released or autoreleased. It's also pointing to a lot of not-mine (say QuartzCore) methods/classes.
Also, I don't understand why autorelease is not autoreleasing. I mean, it sometimes looks like an object that is marked for autoreleasing, is released way too late. I haven't created any NSAutoreleasePools myself, so is it possible that the pool is drained only when the runtime stops? How can I periodically drain the pool (even if it's not mine).
Any help is greatly appreciated.
Kind regards,
Reinder
Used this for the heap checking: http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/
Are you using imageNamed to load your images - this method will keep all images cached in memory. Try initWithContentsOfFile instead.
Watch out though; initWithContentsOfFile: won't cache at all so if you use this method a lot for the same image then you should be using imageNamed:!
I think you might want to try to optimize your design first and read guides for efficent memory management. A better understaning of the components and the runtime helps more than tracking memory allocations and will make it easier to find the leaks.
First you should always use release. Only use autorelease when necessary.
Make sure you follow the guidelines for UITableView implementations and efficient management of UITableViewCells (lazy loading, cell reusing etc.).
Check if you have retain-cycles (retained view controllers won't be deallocated).
Track the deallocation of your view controllers and objects
Don't keep stuff in memory you don't need anymore.
Don't load stuff you don't need right now.

Garbage Collection leak? Scripting Bridge leak?

I'm always really picky about memory leaks and I cannot understand why my garbage collected application leaks. My code is entirely memory-managed and it runs great without garbage collection, not a single leak. However, as soon as I turn on garbage collection it leaks!
Just to prove a point, why does this leak in a garbage collected app? (place this dummy code at applicationDidFinishLaunching:)
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel beginSheetModalForWindow:window completionHandler:^(NSInteger result) {NSBeep();}];
Also, is there a way to prevent leaks in apps (garbage collected or otherwise) that use Scripting Bridge? it seems as if they all leak, even the sample ones in xcode.
Thanks everybody!
Here's a partial answer.
In most managed languages, each structure capable of holding references to another object embeds information on which offset can hold a memory address. For instance, in each stack frame, there's a place that tells the garbage collector where to look for addresses.
C-based languages like Objective-C don't have that.
For program correctness, it's better to have a little too many objects than to deallocate objects too early. Therefore, the garbage collector in Objective-C looks for patterns that look like addresses, but cannot know for sure if they are indeed addresses. This may (and is almost bound to) result in false positives for references (and is incompatible with certain memory management techniques you could use with C). Therefore, certain objects can outlive their usefulness until some random integer ceases to exist.
Also, how do you tell what's a leak? Did you just compare the memory footprint, or you checked them through the 'Leaks' instrument? Did you try the 'GC Monitor' instrument?
Sorry I forgot to mention it, I use the "Leaks" instrument in Instruments. There's where I see the leaks. I haven't tried the "GC Monitor" instrument yet. The leaks are small and I can't trace them back to my code using the extended detail.
I've always done my memory management the old-fashion way, so in essence I'm a GC newbie.
So this with GC pattern is normal? Should I just ignore it?