• 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: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful


  • Subject: Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
  • From: John Engelhart <email@hidden>
  • Date: Thu, 7 Feb 2008 01:14:10 -0500


On Feb 6, 2008, at 8:48 PM, Chris Suter wrote:


On 07/02/2008, at 12:06 PM, John Engelhart wrote:

However, consider for a moment if it was a type attribute, and followed type attribute rules, and how this would effect the examples cited. Off the top of my head, I think treating it as a type attribute would have prevent every single error I've pointed out. Hypothetically, consider if UTF8String propagated the __strong type, and the assignment of its pointer to the ivar 'const char *'.

The compiler would fail to compile the code, and generate an error.

I don't think it should be a type qualifier. It would mean that you wouldn't be able to do things like:


puts ([myString UTF8String])

without getting a compiler warning.

This is a pretty debatable point, with pros and cons on each side. My opinion is that you should not be handing pointers which require write barriers for proper operation of the GC system to code that is not compiled with the proper support. One could argue that the decision to require that "all frameworks must be GC compiled/capable" makes this policy a requirement.


Since the GC system considers everything on the stack to be a live pointer, this has the effect of catching 99.99% use of pointers in this fashion. While I do not have a specific example to show here, I think you'll agree that there are occasionally times when calling a C library function will violate these principles. Realistically, when you call a function, that pointer vanishes down a call stack that is surpassingly complex, and that pointer has a tendency of visiting places you would not think applies in a particular case. If you've used Shark.app, I'm sure you've seen some functions which end up creating some surprisingly deep call-stacks that in turn are calling all sorts of seemingly unrelated functions.

I don't argue that it covers 99.99% of the cases. It's that last tiny bit that I'm writing about. I'm sure you'll agree that tracking down errors of this nature is, politely, frustrating.

There's an example someone once used to underscore how optimistic we can be and spectacularly misjudge the likelihood of these rare errors occurring. It comes from the canonical example of multi-threaded/ multi-cpu programming:

x++;

I'll skip over the specifics, but the question is asked "How likely do you think the condition is for two threads to get into a race condition and incorrectly update 'x'? A million to one?"

While a million to one odds seems like a lot, at two gigahertz, that's roughly 2000 times per second. That's roughly a 500 microseconds mean time to failure rate.

Oddly, I had to add a second NSLog() in order to get some kind of lossage, but I think it's fair to chalk this up to the semi-random nature of allocations.

I think that would have been because the pointer returned by UTF8String was still on the stack or in a register.

Hard to say. I think it does illustrate another point: the seemingly random nature in which you will get bitten by these kinds of bugs.



The above example is now perfectly legal by everyones definition of how things were under retain/release, and I correctly clear the pointer before it goes out of scope, and demonstrates that the GC system can, and does, reclaim live data out from under you.

I think your example is contrived. Whilst it's legal in the retain/ release world you wouldn't ever write anything like that.

Granted, my example is contrived, no two ways about it. But is that not the point? To create a compact example which replicates the problem? I believe I have done all that is required: demonstrate that it is possible. Once I've done that, the sheer volume of code under consideration essentially guarantees that this is taking place. My practical, hands on experience suggests this (and by this, I don't mean this particular example per se, but the ease in which it's possible to get some of these subtle points wrong) is happening far more frequently then you would think.



The solution to all of this is, as has already been stated, is to understand the contract that UTF8String promises and to make your own arrangements if you want to hang on to the value.

You're absolutely right. But my point is that, in practice, this is not quite as clear cut as it seems.


Allow me to back way, way, way up. For the purposes of this argument, let us not consider all the technical points that have been discussed so far, as it's easy to get lost arguing pedantic, nuanced details. Let's consider the GC system from a purely pragmatic point of view.

Now, the precise specifics not withstanding, you will at some time get some small detail wrong. You will have created a bug with regards to some GC detail. The effect of this bug, which I think everyone will reasonably agree on, is likely to result in the collector reclaiming memory that you have in use when you clearly didn't want it to.

The hows and whys of your bug aren't really important, but you have done something wrong when you shouldn't have. These things happen.

My experience with these bugs has been that they consume an EXTRAORDINARY amount of time to track down. Because of the semi- random nature that these bugs manifest themselves in, I have found that it's virtually impossible to find a solid set of conditions to tickle the condition. I have found that unit tests are worthless in trying to track down these problems. The complex interactions required to tickle these bugs are essentially impossible to create with unit tests. All unit tests will pass, flawlessly, and in fact it some times may not be possible to recreate the right conditions to trigger the bug because essentially all your variables are sitting on the stack in the scope of the unit test.

The pragmatic effects of using Leopards GC system has been a MASSIVE increase in the amount of time I have spent debugging problems that have all the symptoms of "race condition" bugs, and consequently the huge uptick in effort required to find and eliminate these bugs.

This is my warning to you (you being all of the list, or archive reader). Setting aside all the technical points discussed, you will eventually create a bug that in retrospect, you clearly shouldn't have. The nature of these bugs means that it will take tremendous effort and time to track down and correct. My experiences with the GC system have seen the time I spend debugging explode, and in fact dominate the time I spend developing. What's worse is that these bugs rarely manifest themselves during development and are nearly impossible to catch with unit tests. This means that the reliability of "shipped code" goes right through the floor, and replicating the bug often requires considerable interaction with an outside party and all the difficulties that that entails.
_______________________________________________


Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: John Engelhart <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: Alastair Houghton <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: John Engelhart <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: Chris Hanson <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: John Engelhart <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: "Hamish Allan" <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: Alastair Houghton <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: John Engelhart <email@hidden>)
 >Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful (From: Chris Suter <email@hidden>)

  • Prev by Date: Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
  • Next by Date: Re: Autocomplete word as you are typing
  • Previous by thread: Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
  • Next by thread: Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
  • Index(es):
    • Date
    • Thread