Let me know if I understand memory management...

Discussion in 'Mac Programming' started by cult hero, Aug 4, 2010.

  1. cult hero macrumors 6502a

    cult hero

    Jun 6, 2005
    After writing a few experiments I think I mostly understand memory management in Objective-C. Please tell me if these presumptions are correct (I'm also writing this as a matter of reinforcing my own mind on the matter):

    For object obj:

    1. [obj release] will decrement the object's retain count and if that count is set to 0 then [obj dealloc] will be called right then and there regardless of the autorelease pool.

    2. [obj autorelease] will decrement the object's retain count when the autorelease pool is drained. If that count is 0 then [obj dealloc] will be called.

    3. If obj is created via obj = [[Class alloc] init] or it is explicitly copied via some kind of copy method, I am responsible for releasing it myself.

    4. If obj is created via a "factory method" (such as [NSNumber numberFromInt: x]) it's generally presumed that it was touched by [obj autorelease] before it was returned to me.

    With that said, and presuming it is true, I did notice something when running these experiments last night. If I explicitly release an object that has, more or less, been set to be autoreleased when the pool drains, the program WILL seg fault.

    Question 1: When working with some kind of third party library or something, how do I know that their factory methods have invoked autorelease so I know things will clean when the pool drains?

    Question 2: What if I want a factory created object to be deallocated before the pool drains? Is there a way to REMOVE autorelease counters so that I can explicitly release the object without a seg fault?

    Question 3: Does a memory leak eat up memory AFTER the program terminates? If I fail to properly release objects and the program quits is that memory effectively wasted until a reboot?
  2. lee1210 macrumors 68040


    Jan 10, 2005
    Dallas, TX
    You may have already, but you should always refer here when you are wondering about this sort of thing:

    You own an Object when you get it using a method containing alloc, new, or copy. This is by convention, so every library you are using MUST adhere to these rules, or they will break memory management when they are used. This covers your point #3, though you omitted "new" in your list.

    Your points #1 and #2 are correct.

    As for point #4, what I described above still pertains here. If the method you received the Object from does not contain alloc, new, or copy it must be autoreleased. If it's not, the author of the method did not abide by the rules.

    As for releasing an autoreleased Object, yes, this will cause big problems. Over-releasing an object whether or not autorelease is involved is incorrect and will cause problems. After an Object is deallocated, trying to send a message to it and manipulate it will cause problems.

    To answer Question 1: You don't know, but if they don't adhere to the rules the library is broken, and you probably shouldn't use it. The conventions MUST be followed for memory management to work.

    Question 2: I know of no way to unautorelease an Object. If you need to deallocate autoreleased Objects sooner, setup a new autorelease pool with tighter scope and drain it when you need those things to go away.

    Question 3: Once a program completes (dies or completes successfully) the system reclaims all of its memory.

  3. kpua macrumors 6502

    Jul 25, 2006

    The conventions are that you have "ownership" of the object and are responsible for releasing it when the method starts with "alloc", "new", or "copy". And of course, there's -retain itself.

    By the way, not all "factory methods" that don't pass ownership to you necessarily call -autorelease. Some classes may cache instances and retain them internally, or hold on to them for various other reasons. (This is one reason why you should never inspect the value of -retainCount directly.)

    Any well-behaved third party library must conform to the above conventions, or at least state their own regarding object ownership. If you follow those simple conventions, then you don't even have to think about what the library does.

    You can't force an autorelease pool you didn't create to autorelease an object at will. However, you can create your own autorelease pool if you want to manage the lifetime of objects created by "factory methods".

    Another alternative is to use the alloc/init variant of the factory method so you can manually -release it whenever you want.

    No, all application memory is reclaimed by the system when the application terminates. That doesn't mean that leaked memory doesn't affect system performance however, even after an app quits. If your app leaks memory profusely, then you're creating memory pressure, which forces other applications to page out to disk. When you quit your app and try to use others, then you have to wait for those apps to page back in, which can often result in the SPOD.
  4. whooleytoo macrumors 604


    Aug 2, 2002
    Cork, Ireland.
    I use these quick 'n' dirty rules, to help me understand it better. (Feel free to add/correct, anyone) :

    For every increment, you need a decrement:
    - alloc, copy, retain increment the retain count by one.
    - release, autorelease decrement it by one.

    When to use autorelease:
    - If you create an object (via alloc or copy) in a method, and want to return it; you typically autorelease it (for obvious reasons, release won't work).

    When to retain:
    - If a method returns an object to you, don't make any assumptions about its retain count. If you only need it in the current scope, no problem. If you want to assign it to a instance variable and reference it later, make sure you retain it (& then release when done with it).

    When to create "extra" autorelease pools:
    - I believe you need to create autorelease pools for new threads you create.
    - If you have a tight loop in which lots of autoreleased items are created, it may be a good idea to create a pool so that these objects don't build up dramatically before the outer pool has a chance to empty.

    Hope this helps/or at least doesn't hinder!
  5. chown33 macrumors 604

    Aug 9, 2009
    Sailing beyond the sunset
    My list of rules is pretty short:
    1. Do I own the object? If I do, then I'm responsible for releasing it. If I don't, I'm not.

    2. If I don't own the object, and I need to, then I take ownership by calling retain. Thereafter, rule 1 applies.

    I think it's a lot easier to approach and understand as ownership, rather than a bunch of mechanistic cases based on retain-count.
  6. whooleytoo macrumors 604


    Aug 2, 2002
    Cork, Ireland.
    That's a lot simpler alright!

    It does depend on you (or 'the reader') knowing precisely what "owning the object" is. :)

    (Writing technical documentation must be a nightmare. Too much information and people's eyes begin to glaze over. Too little, and it's ambiguous and needs more discussion).
  7. cult hero thread starter macrumors 6502a

    cult hero

    Jun 6, 2005
    That cleared up pretty much any remaining confusion.

    Thanks. I'll also read the developer guide linked from Apple's site. I'm just starting to dig into this stuff, but there is SO MUCH information that it's almost overwhelming. Although I have been coding for years, I've done little more than dabble in compiled languages. I think I'm over thinking some things and am presuming others are more complicated than they really are.

    It looks like the real key for some of the forward thinking I was doing is to create additional autorelease pools. I'll need to read up on that in depth later, but it's probably not that important at the moment. I'm probably being a little too zealous in my thoughts about managing memory. We'll see.

    Thanks again everyone.
  8. chown33 macrumors 604

    Aug 9, 2009
    Sailing beyond the sunset

Share This Page