iPhone/Instruments: what's about the "malloc" entries in object summary? - iphone

I'm performance tuning my iPhone/iPad app, it seems like not all the memory gets freed which should be. In instruments, after I simulate a memory warning in my simulator, there are lots of "Malloc" entries left; what's about them? Can I get rid of them, what do they mean/what do they stand for?
Thanks a lot,
Stefan

At any time, your app will have a (huge) number of living objects, even after getting a memory warning (and the subsequent memory recovery by the operating system). So, it is pretty common that you will also see many of those mallocs you are seeing.
They are not in themselves a sign that something is wrong with memory allocation, but possibly only of the fact that your program is running.
Also have a look at this S.O. topic to learn more about the object allocation tool.
Furthermore, there are many advanced techniques you can use to detect memory allocation problems.
Here you can find a great tutorial that will allow you to go way beyond what the Leaks tool allows you to.
EDIT:
About the exact meaning of those mallocs, you have to think that you can allocate two broad classes of objects (to put it roughly): Objective-C objects that are created through the Obj-C runtime system, and "normal" C objects, that are allocated through malloc.
Many object of the second class are allocated (without you directly calling malloc) by system libraries and by the compiler C library (think about, e.g., sockets or file handles, whatever). Those (C) objects do not have type information associated to them, so Instruments simply shows you the size of the allocated memory block, without having more information available.
Many times malloc objects are created by higher-level classes, so that when you recover memory associated to their instances, also memory allocated through malloc is freed.
You should not worry specifically about them, unless you see that their overall size "grows indefinitely" along program execution. In such case you need first to investigate the way you alloc/release your higher level objects and understand where in your code things get stuck.

Related

What is the difference between Objective-C automatic reference counting and garbage collection?

With the new automatic reference counting (ARC) introduced in Xcode 4.2, we no longer need to manually manage retain / release in Objective-C.
This seems similar to garbage collection, as done in Objective-C on the Mac, and in other languages. How does ARC differ from garbage collection?
As I describe in my answer here, ARC can provide the best of both manual memory management and tracing garbage collection. It mostly removes the need for a developer to track manual retains, releases, and autoreleases on Objective-C objects, yet avoids the need for a garbage collector process which can use up limited resources on a mobile device and cause occasional stutters in a running application.
ARC inserts the appropriate retains and releases required for reference counting at compile time, by applying the rules that all Objective-C developers have had to use over the years. This frees the developer from having to manage this themselves. Because the retains and release are inserted at compile time, no collector process is needed to continually sweep memory and remove unreferenced objects.
One slight advantage that tracing garbage collection has over ARC is that ARC will not deal with retain cycles for you, where tracing garbage collection can pick these up.
A great read on the subject comes from this thread on Apple's Objective-C mailing list, where Chris Lattner has this to say:
The primary advantage of GC over ARC is that it collects retain
cycles. A secondary advantage is that "retained" assignments are
"atomic" because they are a simple store. ARC has several big
advantages over libauto GC:
It has deterministic reclamation of objects (when the last strong reference to the object goes away) where GC frees an object "sometime
later". This defines away a class of subtle bugs that can exist in GC
apps that aren't exposed because the collector doesn't trigger "in the
buggy window".
The high water mark is generally much lower with ARC than GC because objects are released sooner.
libauto provides a fragile programming model, you have to be careful to not lose write barriers etc.
not all of the system frameworks are GC clean, and the frameworks do occasionally regress as they evolve.
ARC doesn't suffer from false roots. libauto conservatively scans the stack, which means that integers that look like pointers can root
object graphs.
ARC doesn't have anything that kicks in and stops your app, causing UI stutters. libauto is pretty advanced as far as GC implementations
go because it doesn't immediately stop every thread, but it still does
usually end up stopping all the UI threads.
I am currently migrating both my manually memory managed projects, as well as those using Objective-C garbage collection, to ARC. After using garbage collection in a couple of Mac applications for a while now, I see some significant advantages in moving these projects to ARC.
ARC rely on a compile time "referenced" objects which make it efficient in a low-power mode environments (Mobile devices).
GC rely on a runtime based "reachable" objects which make it efficient in a multi-threaded environment.
Operation
ARC injects a code into the executable to be executed "automatically" on unused objects depending on their reference count.
GC works in the runtime as it will detect the unused object graphs (will eliminate retain-cycles) and remove them on an indeterminate time intervals
Advantages of Automatic Reference Counting
Real-time, deterministic destruction of objects as they become
unused.
No background processing.
Advantages of Garbage Collection
GC can clean up entire object graphs, including retain cycles.
GC proceed in the background, so less memory management work is done
as part of the regular application flow.
Disadvantages of Automatic Reference Counting
ARC cannot handle retain cycles automatically.
Disadvantages of Garbage Collection
Because GC happens in the background, the exact time frame for object
releases is undetermined.
When a GC happens, other threads in the application may be
temporarily put on hold.
How does ARC differ from garbage collection?
ARC is a form of garbage collection.
You probably mean "what is the difference between ARC and tracing garbage collection (like the JVM and .NET)?". The main differences are that ARC is slower and leaks cycles. That's why the JVM and .NET both use tracing garbage collectors. For more information, please read How do reference counting and tracing garbage collection compare?.
the short and sweet answer is as follow:
GC of java is Runtime, while ARC is compile time.
GC has reference to the objects at runtime and check for the dependencies of object runtime.
While ARC appends the release, retain, autorelease calls at compiletime.

Does iOS 5 have garbage collection?

Do I no longer have to worry about memory management iOS 5 onwards? Also, will all programs written for iOS 4 and earlier versions have to be rewritten to allow iOS to manage the memory for you?
You appear to be talking about Automatic Reference Counting, mentioned in other answers. ARC is a kind of GC in that it automates memory freeing, but has a number of differences from a good garbage collector.
Firstly, it's mainly a compiler technology. The compiler knows about Cocoa's reference-counting guidelines, so it inserts retains and releases where they should be according to the rules. It works just like if you'd written the retains and releases yourself — it simply inserts them for you. Normal garbage collectors keep track of your program's memory while it is running.
Second, since it is just like retain and release, it can't catch retain cycles (if Object A retains Object B and Object B retains Object A, and nothing else references either of them, they both become immortal). You need to take the same precautions to prevent them.
It also uses resources differently from an automatic garbage collector. The garbage collectors used with Objective-C have to scan for unreferenced memory and collect it — which is expensive, and can lead to "stuttering" on slower systems — but they only have to do this occasionally, and in theory can even fine-tune their collection cycles to match how a program actually uses its memory. In general, a GC program will use more memory than a non-GC program and will slow down significantly when the GC decides to collect. ARC, on the other hand, moves the "scanning" to compile-time and frees memory as soon as it's available, but it has to constantly update object reference counts instead of waiting for garbage to build up like a collector.
On Apple's public iOS 5 page, they state:
Automatic Reference Counting
Automatic Reference Counting (ARC) for Objective-C makes memory management the job of the compiler. By enabling ARC with the new Apple LLVM compiler, you will never need to type retain or release again, dramatically simplifying the development process, while reducing crashes and memory leaks. The compiler has a complete understanding of your objects, and releases each object the instant it is no longer used, so apps run as fast as ever, with predictable, smooth performance.
It's a compiler feature; not an OS feature so I don't see why it wouldn't work with older versions.
Automatic Reference Counting
implements automatic memory management
for Objective-C objects and blocks,
freeing the programmer from the need
explicitly insert retains and
releases.
You will worry less about memory management. There is public info available on the subject:
ARC replacing GC? (lists.apple.com)
Automatic Reference Counting (clang.llvm.org). This is the tech spec on ARC.
If the spec is too harsh to read, in short, you will need to edit the retain/release code to use ARC, but old programs remain compatible. What you shouldn't do is mix both.

what is NSZone? What are the advantages of using initWithZone:?

There are so many functions like
1. NSDefaultMallocZone()
2. NSCreateZone();
3. NSRecycleZone();
4. NSSetZoneName();
5. NSZoneMalloc();
and many more related to NSZone
What does NSZone means, where to use these functions and when?
What are the advantages of initWithZone: and how to use in my iphone app?
NSZone is Apple's way of optimizing
object allocation and freeing. NSZone
is not an object; it is an opaque
C-struct storing information about how
memory should be handled for a set of
objects.
One rarely needs to worry about
handling your own zones in
applications; Cocoa handles it
transparently. A default NSZone is
created on startup and all objects
default to being allocated there. So
why would you want to use your own?
If you are mass-allocating hundreds of
cheap objects, you may find the cost
of actually allocating space for them
becomes significant. Because the
standard zone is used all the time, it
can become very patchy; deleted
objects can leave awkward gaps
throughout memory. The allocator for
the standard NSZone knows this, and it
tries to fill these gaps in preference
to grabbing more memory off the
system, but this can be costly in time
if the zone has grown quite large.
If you want to mass-allocate objects,
then, you can create your own zone and
tell it not to bother with finding
gaps to put new objects in. The
allocator can now jump to the end of
its allotted memory each time and
quickly assign memory to your new
objects, saving a lot of effort.
Allocators can save you time
elsewhere, too, as asking the OS for
more memory, which a zone needs to do
whenever it fills up, is another
costly operation if it's done a lot.
Much quicker is to ask for huge chunks
of memory at a time, and you can tell
your NSZone what to do here as well.
Rumor has it that NSZone could save
you deallocation time in the Good Old
Days, too, with a method that simply
chucks away all the allotted memory
without bothering to call
deallocators. If a set of objects is
self-contained, this could save a lot
of time, as you can chuck them all
away at once without tediously
deallocating them all. Alas, there
appears to be no sign of this godsend
in the current documentation; the
single NSZone method (NSRecycleZone?)
carefully puts all the objects in a
zone neatly on the default NSZone. Not
exactly a huge time-saver.
So, in summary, zones save you time in
mass allocations. But only if
programmers know how to use them!
From CocoaDev

Memory leak tool tells me zero leaks but memory footprint keeps rising

I'm running through some memory profiling for my application in SDK 3.2 and I used the 'Leak' profiler to find all my memory leaks and I plugged all of them up. This is a scrollView navigationController application where there are tiles and you click a tile which goes to a new view of tiles and so on, I can go many levels deep and come all the way back to the top and the 'Leak' profiler says everything is cool.
However, if I watch the memory footprint in the 'ObjectAlloc' profiler the memory footprint goes up and up as I go deeper (which seems reasonable) but as I back out of the views the memory footprint doesn't go down as I'd expect.
I know this is a vague description of the app but I can't exactly post a gillion lines of code :) Also it should be noted I'm using coreData to store image data as I go so the database is growing in size as more nodes are chosen, dunno if/when that is released from memory.
What gives?
This sounds like it could be one of a few things:
Memory not given back to OS after deallocation. This is a common design for C runtimes. When you do an allocation the C runtime allocates more memory for its use and returns a chunk of it for you to use. When you do a free the C runtime simply marks it as deallocated but doesn't return it back to the OS. Thus if the Leak Tool is reading OS level statistics rather than C runtime statistics the Leak tool will fail to report a corresponding decrease in memory usage.
Misleading values reported by Leak Tool Memory. The Leak Tool could be looking at different values than the C runtime and is reporting values that will cause you concern even though nothing is wrong (just as people try to use Task Manager in Windows for detecting leaks and get very confused with the results because it is a very poor tool indeed for that job).
Fragmentation. It is possible that your application is suffering from memory fragmentation. That is when you allocate, then deallocate then allocate, subsequent attempted allocations are larger than the "holes" left by deallocations. When this happens you fragment the memory space, leaving unusable holes, preventing large contiguous memory blocks and forcing the usage of more and more memory space until you run out of memory. This is a pathological condition and the fix is typically application specific.
I think the first of these three suggestions is most likely what is happening.
Depending on how you have your object graph constructed in Core Data, it's memory use can grow unexpectedly large.
A common mistake is to store objects inside a complex and often faulted (loaded into memory) entity. This cause the big blob to be loaded/remain in memory whenever any other part of the entity is referenced. As you object graph grows, it eats more and more memory unless you actively delete objects and then save the graph.
For example: You have an person entity with lots of text info e.g. name, address, etc as well as a large photo. If you make the photo an attribute of the person entity it will be in memory anytime the person entity is faulted. If you get the attribute name, then the photo attribute is in memory as well.
To avoid this, blobs should be in their own entity and then linked to other entities in relationships. Since relationship objects are not faulted until they are called directly they can remain out of memory until needed.
Just because there are no refcount-based leaks, doesn't mean that you're not stuffing something off in a Dictionary "cache" and forgetting about it; those won't show up as leaks because there are valid references to it (the dict is still valid, and so are the refs to all its children). You also need to look for valid, yet unnecessary refs to objects.
The easiest way is to just let it run for too long, then sort object counts by type and see who has a gigantic number - then, track down the reference graph (might be hard in Obj-C?). If Instruments doesn't do this directly, you can definitely write a DTrace script to do so.
To reiterate:
char *str1 = malloc(1000);
char *str2 = malloc(1000);
.
.
.
char *str1000 = malloc(1000);
is not a memory leak, but
char *str1 = malloc(1000);
char *str1 = malloc(1000); //Note! No free(str1) in between!
is a memory leak
The information on core data memory management is good info and technically the answer by Arthur Kalliokoski is a good answer re: the difference between a leek and object allocation. My particular problem here is related to an apparently known bug with setBackgroundImage on a button in the simulator, it creates a memory 'leak' in that it doesn't release ever release the memory for the UIImage.
You can have a continuously growing program without necessarily leaking memory. Suppose you read words from the input and store them in dynamically allocated blocks of memory in a linked list. As you read more words, the list keeps growing, but all the memory is still reachable via the list, so there is no memory leak.

Obj-C circular buffer object, implementing one?

I've been developing for the iPhone for quite some time and I've been wondering if there's any array object that uses circular buffer in Obj-C? Like Java's Stack or List or Queue.
I've been tinkering with the NSMutableArray, testing it's limits... and it seems that after 50k simple objects inside the array - the application is significantly slowed down.
So, is there any better solution other than the NSMutableArray (which becomes very slow with huge amounts of data). If not, can anyone tell me about a way to create such an object (would that involve using chain (node) objects??).
Bottom line: Populating a UITableView from an SQLite DB directly would be smart? As it won't require memory from an array or anything, but just the queries. And SQLite is fast and not memory grinding.
Thank you very much for you time and attention,
~ Natanavra.
From what I've been thinking it seems that going for Quinn's class is the best option possibly.
I have another question - would it be faster or smarter to load everything straight from the SQLite DB instead of creating an object and pushing it into an array?
Thank you in advance,
~ Natanavra.
Apologies for tooting my own horn, but I implemented a C-based circular buffer in CHDataStructures. (Specifically, check out CHCircularBufferQueue and CHCircularBufferStack.) The project is open source and has benchmarks which demonstrate that a true circular buffer is quite fast when compared to NSMutableArray in the general case, but results will depend on your data and usage, as well as the fact that you're operating on a memory-constrained device (e.g. iPhone). Hope that helps!
If you're seeing performance issues, measure where your app is spending its time, don't just guess. Apple provides an excellent set of performance measurement tools.
It's trivial to have NSMutable array act like a stack, list, queue etc using the various insertObject:atIndex: and removeObjectAtIndex: methods. You can write your own subclasses if you want to hardwire the behavior.
I doubt the performance problems you are seeing are being caused by NSMutableArray especially if your point of reference is the much, much slower Java. The problem is most likely the iPhone itself. As noted previously, 50,000 objective-c objects is not a trivial amount of data in this context and the iPhone hardware may struggle to managed that much data.
If you need some kind of high performance array for bytes, you could use one of the core foundation arrays or roll your own in plain C and then wrap them in a custom class.
It sounds to me like you need to switch to core data so you don't have to keep all this in memory. Core data will efficiently fetch what you want only when you need it.
You can use STL classes in "Objective-C++" - which is a fancy name for Objective-C making use of C++ classes. Just name those source files that use C++ code with a ".mm" extension and you'll get the mixed runtime.
Objective-C objects are not really "simple," so 50,000 of them is going to be pretty demanding. Write your own in straight C or C++ if you want to avoid the bottlenecks and resource demands of the Objective-C runtime.
A rather lengthy and non-theoretical discussion of the overhead associated with convenience:
http://www.cocoabuilder.com/archive/cocoa/35145-nsarray-overhead-question.html#35128
And some simple math for simple people:
All it takes to make an object as opposed to a struct is a single pointer at the beginning.
Let's say that's true, and let's say we're running on a 32-bit system with 4 byte pointers.
4 bytes x 50,000 objects = 200000 bytes
That's nearly 200MB worth of extra memory that your data suddenly needs just because you used Objective-C. Now compound that with the fact that whatever NSArray you add those objects to is going to double that by keeping its own set of pointers to those objects and you've just chewed up 400MB of RAM just so you could use a couple of convenience wrappers.
Refresh my memory here... Are swap files on hard drives as fast as RAM? How much RAM is there in an iPhone? How many function calls and stack frames does it take to send an object a message? Why isn't IOKit written in Objective-C? How many of Apple's flagship applications that do a lot of DSP use AppKit? Anybody got a copy of otool they can check with? I'm seeing zero here.