Developers continue to debate the question of memory management solutions. Which is best? Although Objective-C’s retain/release runs smoother and faster than Java’s garbage collection, it places a much larger burden on the developer and introduces a much larger risk of memory leaks.In the first of a series of articles that detail the important differences between Java and Objective-C, Marcus Zarra compares and contrasts memory management in Java and Cocoa/Objective-C.
Maven is an incredibly powerful tool that allows for the easy maintainability of Java projects. But what if your project is more complex than a simple Hello World applet? Marcus Zarra introduces the Maven multiproject concept, which is designed to facilitate the management of complex projects.
Well, while you *can* make mistakes in ObjC and leak memory, it’s just as easy to leak a non-memory resource (file handle, window) in Java.
If you follow a single rule it’s easy to get memory working all fine in ObjC: everything that you either create (alloc), or copy, or retain has to be released; everything else not.
The only thing to avoid are cycles, but hey, how often do you really want to create cycles in your application?
Retention of limited resources (file descriptors, sockets, windows, fonts, etc) is a comparatively small proportion of object retentions. Exhausting limited resources while quite possible, is not in general comparable to the error-prone nature of semi-manual reference-counting. If you remove the errors caused by N% through general object retention but provide little to prevent exhaustion conditions that exist in both environments, it hardly seems sensible to suggest that makes it worse.
One thing, that I keep hearing, is that any referenceCount scheme suffers from CPU cache wastage. Basically, everytime you want to keep an object for yourself (retain) you have to touch the referenceCounter (or retainCounter), well not sure how bad that is. Started learning Objective C, myself couple of months ago (even bought WebOjects 4.5 from ebay.com to get up to speed on my Windows machine).
There is some overhead in managing the refcounts, especially since ObjC does dynamic method calls. Without dynamic calls, managing refcounts should be quite fast, as a modern CPU can do this in parallel with other operations. Loading the object into cache will also load the refcount, so the overhead is quite small.
There is some overhead in managing the refcounts, especially since ObjC does dynamic method calls.
Apple’s implemtation can avoid some of this overhead by using direct CoreFoundation refcounting calls.
There is overhead in maintain a reference count, both in bus traffic (reading and writing the reference count) and in code (to update/maintain the reference count). This overhead is one of the reasons that .NET uses a garbage collector and not reference counting-based memory management, as was discussed here:
http://discuss.develop.com/archives/wa.exe?A2=ind0010A&L=DOTNET&P=R…
In the first example in the “Objective-C Retain/Release” section the author mentions a memory leak by not releasing a pointer before re-assigning it – is there no way to throw a debug message when this happens?
Is there not some system of memory management help/tracking that can be invoked? and yes I realise this could be quite difficult on complex code, I don’t quite understand why its so mutually exclusive on garbage collection or manual control – why can’t you have the choice to use auto-garbage collection or manual mem management?
Any language guru’s care to comment why its all or nothing?
Ta
S
Of course by actaully reading the article instead of looking at the words I would have course absorbed the bit about “autorelease pools”.
But still – are no options for help on memory management?
S
Any recent Java implementation does not use reference counting. Even the primitive ones that do probably never used a collection sweep to deallocate the zero-ref-count objects. I have no idea where this guy got that idea.
Also, he says that ObjC reference counting is “smoother and faster”. Smoother, yes (as in lower latency). The “faster” part is questionable. Garbage collection is pretty fast because it kinda operates in “batch mode.”
Anonymous: You can mix garbage collection and manual memory management. Microsoft’s Managed C++ allows this, for example.
Malkia: Yes, reference counting does burn a lot of CPU when the increment/decrement operations are inserted by the compiler. When you’re manually incrementing and decrementing reference counts (as in ObjC), you can do it less frequently (because you know things about your program’s behavior that a compiler can’t infer). By the way, the common C++ technique of implementing reference counting in a library is even slower than when the compiler inserts them.
In the article, it’s written that the following code (look also that it returns fname, which is not declared anywhere locally):
– (NSString *)formattedName {
NSString *initString = [[NSString alloc] initWithFormat:@”[%@]”, name];
NSString *tempString = [NSString stringWithFormat:@”[%@]”, name];
NSString *copyString = [tempString copy];
return fname;
}
returns these retainCounts:
“In this example, the retain count on initString and copyString is 1. However, the retain count on tempString is 0. The reason for this difference is because of the way they are instantiated.
Because initString is created by using the init method, its retain count is incremented. As part of the init process, the object’s retain count is automatically incremented.”
Now I’ve tried this at home, and it gave me different results.
Compile the next one with gcc -foundation Framework test.m -o test
#import <Foundation/Foundation.h>
NSString* name = @”Shmuck”;
int main( int argc, char *argv[] )
{
NSAutoreleasePool* autoreleasePool = [NSAutoreleasePool new];
NSString *tempString = [NSString stringWithFormat:@”[%@]”, name];
NSString *copyString = [tempString copy];
NSString *initString = [[NSString alloc] initWithFormat:@”[%@]”, name];
NSLog( @”name retainCount = %d”, [name retainCount] );
NSLog( @”initString retainCount = %d”, [initString retainCount] );
NSLog( @”tempString retainCount = %d”, [tempString retainCount] );
NSLog( @”copyString retainCount = %d”, [copyString retainCount] );
[autoreleasePool release];
}
it gave me other story:
2005-09-27 12:01:16.718 test[1999] name retainCount = -1
2005-09-27 12:01:16.742 test[1999] initString retainCount = 1
2005-09-27 12:01:16.744 test[1999] tempString retainCount = 2
2005-09-27 12:01:16.746 test[1999] copyString retainCount = 2
is the artcile okay, or did I did something wrong (I’m still learning so it’s possible)?
> Java employs an automatic garbage collection system to
> manage memory inside the virtual machine. This garbage
> collection is handled via reference counting. Each
> instance/object inside of the virtual machine has a
> reference count. When that reference count reaches
> zero, the object is “garbage,” and should be removed
> and its memory released.
Boy that has to be embarrassing for the author. He’s a big time Enterprise Developer(tm).
Hi,
There’s book on that topics (Algorithms) for C++, C etc. but what about Objective-C?
Any reference, tutorial etc ?
Thanks
/kml
> …why can’t you have the choice to use auto-garbage collection or manual mem management?
With Objective-C, you _do_ have a choice, as there’s nothing that prevents you from hooking up a “real” garbage collector to Objective-C. In fact, I remember reading a rumor that Apple is working on that. Certainly, they seem to be somewhat headed in that direction, anyway, given that they now recommend using “return [[anObj retain] autorelease];” in accessor methods instead of simply “return anObj;”, since they surely realize how easy it is to screw up with manual memory management.
The GNU runtime can be compiled with support for the Boehm conservative garbage collector, and POC works with it as well. There are of course limitations and caveats to using garbage collection in a C language.
I think the point of “return [[anObj retain] autorelease]” is simply to be able to create a non-copy/alloc function. Your caller expects the return value to be autoreleased.
For instance, if you fetch something out of an NSArray, you have to retain it (otherwise it could go away), but you also have to autorelease it because your function isn’t called copy*** or alloc***.
Nothing more and nothing less.
Maven is really powerful and all, but, that comes with a cost… it’s _way_ too complex. Specially if you’re doing multiprojects (i’ve had some experience with that).
I think Ant just does the job of building software pretty fine, in 99% of the situations.
Maven can also do some stuff Ant can’t do (like, generating reports, website, etc); but i think a better approach is to get individual projects that do that much better (like, a wiki for website, etc).