• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Memory Management
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Memory Management


  • Subject: Re: Memory Management
  • From: Marcel Weiher <email@hidden>
  • Date: Thu, 31 Jul 2003 02:23:29 +0100

[..]

This is thinking in another language, and forcing Foundation / Objective-C into that mindframe. It doesn't help putting "garbage collection" as a concept or a goal to be aspired to, into this mail thread.

Where on earth did you get that from?!? Reference counting is a form of garbage collection. Retain/release, of course, is not fully automatic garbage collection, because it is at best semi-automatic.

The problem that autorelease pools actually solve is that of returning values from one context to another when there are no further outstanding references.

What other systems that employ reference counting garbage collectors (such as earlier Smalltalks) would do is increment the reference count of the returned value when in transit to the caller, and then decrement it again once it has been received by the caller's context (where the refCount was incremented due to assignment). If you didn't do that, you would lose the object on the way back (see above).

Of course, you can't actually do that with Objective-C with library code, because you don't have the same kind of control over the semantics of method/function calls. Autorelease pools solve that problem very nicely, by extending the life of the object enough so it can survive the 'limbo' while it is being returned.

Anyway, all this is only necessary when the callee does not hang on to the object. If the callee does hang on to the object, there simply is no *need* to extend the life of the object.

[examples]


What I'd like to add is this. Sharing a return value between caller and method ideally should be fail safe.

There are several levels to this statement.

At the most general level you are asking for referential transparency, something you are never ever going to get in an imperative language, and Objective-C is always going to remain an imperative language.

However, I think it is very good that you did bring it up in this generality, because I think that this is the (somewhat hidden) motivation behind some of the things that are being said. I find this motivation understandable, because referential transparency is a nice thing to have. However, the only way to actually get referential transparency is to have a language designed from the ground up to support it. It is one of these things that you absolutely cannot bolt on to a language after the fact. How this usually works is that there are *no* references whatsoever, only values. So there can never be aliasing of pointers/references because there are no pointers/references. Conceptually, everything is copied all the time. So if you insert an element into a collection, a new collection is created that has the element inserted at the right spot. The old collection is not modified. Nothing is ever modified.

*That* is how you get referential transparency. Autorelease pools don't cut it, not by a long shot. As you can imagine, it is expensive like hell, and the languages that have it have to optimize like crazy to safely transform all these copies into imperative updates.

To be fail safe the returned value must be under ownership of the caller.

If the caller wants *ownership* then it must retain the result. The object ownership rules are very clear about this. In fact, this is one of the points I find highly dubious about the whole autoreleasing-accessors idea: instead of making it clear that you now want ownership of that object, you rely on it being in autorelease-limbo without need.

[..]

If the memory is owned by the caller, then there is no problem, the caller temporarily grants read/write access to its memory area, and can peruse it at will on return:

- (void) getName:(NSMutableString *) s
{
[s setString:name_];
}

-(void)getName:(NSMutableString*)s
{
[s release];
}

And the release could just as well happen because of a side effect of what you are doing. This is no more safe than the return. And on the other hand, the return is just as safe, because it is 'sharing' between *objects* not method contexts.

If the memory is solely owned by the method (instance), this means a weakening in the fail-safeness

(a) it isn't fail safe and (b) sharing between objects is just as safe/unsafe.

- (NSString *) name
{
return( name_);
}

This transfers a pointer to memory, not owned by the caller.

In the first case, you also transfered a pointer to memory, from the caller to the callee. This is just as unsafe because the callee could have released the memory. There is no difference!

If name_ gets set to something else as a side effect to another call to that instance, I can expect crashes, because the previously returned value might now point to invalid memory.

Yes, that is the fundamental feature of sharing. If you don't want that, you need referential transparency (see above).

This method provides therefore only a limited kind of read access to the return value. That limited access says, you may access that value, if you know, that it hasn't changed in the mean time. (In 99% of all cases, I think you will be able to say, yes I can do that :), otherwise you'd have problems using NSMutableArrays)

Or anything that is imperative programming for that matter...

[callee doing extra retain]


The reason why you get these funny problems when name_ is mutable is, because you are not yielding access completely, the contents are still subject to change by the messaged instance. That's why using copy] autorelease] would be proper, as it also gives the full access rights of the return value contents to the caller (within the scope... bla bla).

Once again, being mutable and sharing is inherent in an imperative programming language. The fact that you are saying one should be copying values is a strong indication that you are after referential transparency. I can just repeat that you aren't going to get it in Objective-C. ever, and you'll waste a lot of cycles not getting it... ;-)

I am not promoting the use of retain] autorelease] (I dislike slowness :)), but I don't mind it to be the documentation default.

I do.

1) It creates more problems than it solves (masking/delaying erros until the autorelease pool pops)
2) The problem it 'solves' is exceedingly rare in practice
3) It actually doesn't even 'solve' that, because important cases are exceptions (collections, 'performance critical' code)
4) The real solution in those exceedingly rare cases that need it is trivial: let the caller retain
5) Having the retain in the calling code makes it intention revealing, showing what you actually wanted to do at that point
6) Due to (4) it complicates the rules instead of simplifying them
7) It also complicates object lifetimes / the object ownership rules
8) It creates expectations of "safety" that an imperative language can never fulfill
9) The cases where it applies are cases where you need to think about your sharing semantics anyhow (see 5)
10) The performance cost (factor 10) is quite significant, and non-localized
11) KISS says: just say no! ;-)

That being said, I have no problem with it being listed as an option, and people deciding what they want to do. However, I do have a problem with it being listed as the default, most of all because of (8. Each time this subject comes up and more and more really smart people fall into similar traps about the 'safety' of the technique convinces me more and more that there is a real problem.

Marcel

--
Marcel Weiher Metaobject Software Technologies
email@hidden www.metaobject.com
Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc.
1d480c25f397c4786386135f8e8938e4
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: Memory Management
      • From: Andreas Mayer <email@hidden>
    • Re: Memory Management
      • From: David Elliott <email@hidden>
References: 
 >Re: Memory Management (From: Nat! <email@hidden>)

  • Prev by Date: Re: Memory Management
  • Next by Date: Re: Memory Management
  • Previous by thread: Re: Memory Management
  • Next by thread: Re: Memory Management
  • Index(es):
    • Date
    • Thread