Re: Garbage collector vs variable lifetime
Re: Garbage collector vs variable lifetime
- Subject: Re: Garbage collector vs variable lifetime
- From: Ricky Sharp <email@hidden>
- Date: Sat, 7 Jun 2008 08:59:15 -0500
On Jun 7, 2008, at 8:18 AM, Michael Ash wrote:
It *does* do this. The error is not in the GC, but rather in the
assumption that "declared in the current scope" is equivalent to "is
on the stack frame". This assumption is not valid. The fact that you
can't make this assumption is extremely inconvenient for the situation
being discussed, but that doesn't mean that it's not behaving as
documented.
I did a double-take myself during the start of this thread and took a
while for it all to sink in. I completely agree with what Michael
here and others have been pointing out. Perhaps the following diagram
and comparison to other code will be helpful to others:
- (void)foo
{
[1] NSData* data = [...];
[2] const unsigned char* bytes = [data bytes];
[3] while (condition)
[4] do work on bytes
[5] remaining code which does not operate on either data or bytes
}
Below, let |----| represent a short span of time that covers a
particular line of code. Fill it with # to denote timeframes where
'data' is valid (i.e. cannot be collected). Fill it with $ to denote
timeframes where the GC thread can collect data.
1 2 3 4 5
Main Thread: |#####|#####|-----|-----|-----|
GC Thread : |-----|-----|$$$$$|$$$$$|$$$$$|
- (void)bar
{
[1] NSData* data = [...];
[2] const unsigned char* bytes = [data bytes];
[3] while (condition)
[4] do work on bytes
[5] [data self];
[6] remaining code which does not operate on either data or bytes
}
1 2 3 4 5 6
Main Thread: |#####|#####|#####|#####|#####|-----|
GC Thread : |-----|-----|-----|-----|-----|$$$$$|
You can thus see that for each method, the GC thread can collect
'data' at a point prior to the last statement. Sometimes, as is
'foo', this can be quite 'early'.
I haven't yet moved my app to GC since it's still baselined to 10.4.
When I do migrate, I will have to tackle this specific NSData issue.
For my needs, I'm hoping that a simple copy to a well-formed buffer
will suffice. Performance is not an issue and quantity of bytes is
always small.
I will hope though that within the context of say memcpy, that the GC
thread could not collect data. For example, the following should be
safe:
memcpy(myLocalGCAwareBuffer, [data bytes], numberOfBytes);
Finally, I think that usages of NSMutableData may also be a bit
tricky. In my case I'll probably just obtain a copy of its bytes,
manipulate them and then copy the result back in. Sort of ironic
though in that the inner pointer would have been valid anyhow in such
blocks of code (the NSMutableData instance would be around between the
get and subsequent set of its bytes):
NSMutableData* data = [...];
const unsigned char* bytes = [data bytes];
operate on copy of bytes in GC-aware buffer
[data replaceBytesInRange:...];
___________________________________________________________
Ricky A. Sharp mailto:email@hidden
Instant Interactive(tm) http://www.instantinteractive.com
_______________________________________________
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