views:

142

answers:

3

SO I already know about memory management in objective C, and I never had to know about it while programming in .net (C#). But i still have some questions about how everything is done.

-Why does the code leak in objective c if we allocate an object and not release it?

-Why doesn't this leak in C#?

-What are some advantages and disadvantages of automatic-garbage-collecting?

-Why not use autorelease on every allocated object (Objective C)?

-Is it possible to take care of the memory manually (C#)? so let's say i instantiate an object, and when I'm done i want to release it, and i don't want to wait for the garbage collector to do it?

+4  A: 

The advantage of automatic garbage collection is that you do not have to explicitly free/release your objects as you said. The disadvantage is you cannot be sure when (or even if) any given object instance will be released.

C# has other mechanisms to release other resources like files, or db connections that have to be released detirminitely. For example, using allows you to make sure that IDispose is called on an object for sure.

Garbage collected systems tend to have more memory in use at any given time than a well tuned manual implementation. Of course, you do not have memory leaks.

The quality and performance of garbage collectors can vary quite a bit which is something you may not have a lot of control over. For example, there may be a noticable lag when the GC runs. In .NET, you can call GC.Collect() to tell the GC that now would be a good time but it may or may not listen.

These days Objective-C is also garbage collected on the Mac. On the iPhone it is reference counted though so I assume that is where you are running into the issue.

On garbage collected systems, you can still run into the issue where a an object hangs onto a reference to an object that you would expect to be garbage collected. The garbage collector will not clean-up this up and so the memory is essentially leaked.

In reference counted systems, you do not have to keep track of every object that points at your object instances but you do have to specify that you want them released.

EDIT: I guess I did not say this explicitly - you cannot manually control memory allocation in C#.

Justin
From a c# point of view, automatic garbage collection comes with memory and speed penalties too - because the system has to keep track of all of the variables on the heap and all the references to them. Also when the automatic garbage collector will run cannot be predicted (although it can be called) so you can find poorly written timing code can be adversely affected by the operation of the garbage collector.
Tim Joseph
@Tim - My answer already mentioned that the GC has memory implications and I talked about varying performance of GC implementations. Should I be adding something else to my answer?
Justin
+8  A: 
  • It leaks in Objective-C because Objective-C doesn’t take any action on it. It relies on you doing all the work. It doesn’t leak in C# (more precisely, in .NET) because it employs a garbage collector which cleans up objects that are no longer used.

  • The main advantage of garbage collection is the above: you have far fewer memory leaks. (It’s still possible to have a memory leak, e.g. by filling a list indefinitely, but that’s harder to do accidentally.) It used to be thought that garbage collection has a disadvantage in that it could slow down the program because it keeps doing the garbage collection in the background and you have little control over it. In reality, however, the difference is negligible: there are other background tasks on your computer (e.g. device drivers) running all the time, the garbage collector doesn’t break the camel’s back either.

  • Auto-deallocation (as it is employed in C++ when a non-pointer variable goes out of scope) is dangerous because it opens the possibility to have a reference to it still in existence even after the object has been disposed. If your code then tries to access the object, the process goes kaboom big time.

  • Yes, it is possible to tell C# to release memory by invoking the garbage collector directly (GC.Collect()). However, I have yet to see a case where this is at all necessary. If you actually run out of memory, the garbage collector will already kick in automatically and free as much as it can.

Timwi
You can tell the garbage collector to run, but it will only collect things that it "should"- it won't release your object if there are still references to it, as well it shouldn't. But GC.Collect() is only a hint. It tells the garbage collector that collection would be practical now because we can handle the lag, but it might ignore you if it does't think there's much work to do.
Kistaro Windrider
Objective-C on the Mac has a garbage collector too (not on iPhone at this point).
Justin
+5  A: 

Objective-C isn't a garbage-collected language, so it has no way of knowing that an object won't be used anymore unless you tell it. That's the purpose of the .NET garbage collector: it checks to see which objects can no longer be used by the program, and- at some point- gets rid of them to free up memory. There are no guarantees as to when, or if, it will ever free any given abandoned object; it's just trying to keep memory usage from going out of control.

C# can't release an object without the garbage collector. If you release an object that's still being referenced, your program is going to crash when you try to use that. Which is always the risk of manual memory management, but like all "memory-managed languages", it is trying to prevent you from making exactly that mistake. If you want to explicitly shut down an object's operation, implement the interface IDisposable for that object's type, and use the Dispose() method on that object- essentially a destructor. Be sure you're done with it, of course, and that the object will behave correctly (by throwing exceptions) if something tries to use it after it's been Dispose()d of.

Objective-C is reference-counted. When an object is out of references, it deletes itself. It's not a bad solution to the "is someone still using this object?" problem, except for data structures that refer to themselves; circular data structures will hang around forever unless carefully handled. .NET isn't a reference counter, so it will get rid of circular data structures that can't be reached from running code.

Autorelease is just a "release later", for returning a value that should self-destruct if the code that grabs it doesn't immediately want to hold onto it, as far as I understand. (I'm not an Objective-C programmer, though.) It gets around the "who releases this object?" problem for calls that return an object, without destroying it before the function is finished. It's a special use case, though, and it doesn't make sense in most other cases.

Kistaro Windrider
Autorelease can be used for more than just return values. It can be used to clean up code in functions where you don't want to have a release for everything at the end or where you want to create a variable and pass it to another function without creating a reference. Autorelease can be tricky when starting out though as if you over release an object it can cause the problem to come up later on in your code execution where it may not be clear what the cause of the problem is.
skorulis
I'm no Objective-C programmer, so thanks for the information! I'd like to edit my last paragraph to be more useful. What does autorelease really do? Three minutes of skimming documentation didn't bring total enlightenment, for some reason. :-)
Kistaro Windrider
Objective-C does have a garbage collector but it is only available for Mac OS X.
dreamlax