Re: garbage collection and NSConnection
On Jul 12, 2008, at 13:42 , Michael Ash wrote: http://www.opensource.apple.com/darwinsource/projects/apsl/CF-476.10/CFRuntime.h typedef struct __CFRuntimeBase { uintptr_t _cfisa; uint8_t _cfinfo[4]; #if __LP64__ uint32_t _rc; #endif } CFRuntimeBase; I guess this isn't the right one, then. If you look at the corresponding CFRuntime.c file, I think you'll find that there is logic there for treating part of the _cfinfo as a retain count (look for _CFRetain() ) To Gary, about 16-bit refcounts, I'd imagine that there's some logic in there where if you hit 0x, it considers that to be a flag to use an external refcount instead, at the cost of some speed. Yep. Inline reference counts are an optimization, as such they need to cater to the common case, not to the outliers (which still have to be handled correctly, but don't need to be as fast). Cheers, Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Sun, Jul 13, 2008 at 12:29 PM, Marcel Weiher [EMAIL PROTECTED] wrote: On Jul 12, 2008, at 13:42 , Michael Ash wrote: http://www.opensource.apple.com/darwinsource/projects/apsl/CF-476.10/CFRuntime.h typedef struct __CFRuntimeBase { uintptr_t _cfisa; uint8_t _cfinfo[4]; #if __LP64__ uint32_t _rc; #endif } CFRuntimeBase; I guess this isn't the right one, then. If you look at the corresponding CFRuntime.c file, I think you'll find that there is logic there for treating part of the _cfinfo as a retain count (look for _CFRetain() ) So it does. That'll teach me to take CF structures at face value. Thanks. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Jul 12, 2008, at 8:25 AM, Michael Ash wrote: On Sat, Jul 12, 2008 at 2:25 AM, Marcel Weiher [EMAIL PROTECTED] wrote: So as I said: (a) object allocation slowest (b) out-of-band retain count slow (c) inline retain count much faster than either. Well that all makes sense, thanks. You're very welcome :-) One further question for you, if you will. I got curious and went off hunting for the inline refcount in NSCFString but couldn't find it. Yeah, NSCFString doesn't actually declare any of its instance variables, which are actually those of the private CFString structure it uses. The closest I got was the '_rc' field in CFRuntimeBase, but it's inside an #if __LP64__ clause, so we don't get it in normal code these days. The __CFString struct doesn't seem to have any place to store a refcount. Am I missing something here, or does it only have an inline refcount in 64-bit? No, the inline reference count is available for all CF objects, and not limited to 64 bit. What version of the structure are you looking at? For example http://www.cocoadev.com/index.pl?HowToCreateTollFreeBridgedClass shows this version, which matches what I got from opensource.apple.com /* All CF instances start with this structure. Never refer to * these fields directly -- they are for CF's use and may be added * to or removed or change format without warning. Binary * compatibility for uses of this struct is not guaranteed from * release to release. */ typedef struct __CFRuntimeBase { void *_isa; #if defined(__ppc__) uint16_t _rc; uint16_t _info; #elif defined(__i386__) uint16_t _info; uint16_t _rc; #else #error unknown architecture #endif } CFRuntimeBase; Cheers, Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
Marcel Weiher wrote: uint16_t _rc; Oh, the horror of it all! Only 65,535 objects can retain a string!!! What am I to do when I model all the citizens of the US voting for just one presidential candidate in November, and the retain count overflows?!?! Okay, that's not a real concern for me, but that's the kind of thing where you find hanging chads are the least of your worries. Didn't someone famous once say, Who needs more than 64 KB in a computer? ;-) ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Sat, Jul 12, 2008 at 1:24 PM, Marcel Weiher [EMAIL PROTECTED] wrote: No, the inline reference count is available for all CF objects, and not limited to 64 bit. What version of the structure are you looking at? For example http://www.cocoadev.com/index.pl?HowToCreateTollFreeBridgedClass shows this version, which matches what I got from opensource.apple.com I was looking at: http://www.opensource.apple.com/darwinsource/projects/apsl/CF-476.10/CFRuntime.h It defines: typedef struct __CFRuntimeBase { uintptr_t _cfisa; uint8_t _cfinfo[4]; #if __LP64__ uint32_t _rc; #endif } CFRuntimeBase; I guess this isn't the right one, then. To Gary, about 16-bit refcounts, I'd imagine that there's some logic in there where if you hit 0x, it considers that to be a flag to use an external refcount instead, at the cost of some speed. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
It looks like it was expanded in 10.5, then, but 10.4 and prior use the 16-bit variables. Regardless of whether it handles overflows or not, my little joke was meant to illustrate that too many developers (generally speaking) think that resources (generally speaking) are unlimited and put no thought into what to do if an error occurs or how to handle requirements that are potentially huge. I'm not saying those on this list think this way, but when people say that there's no cost to this or that approach, I just want to say, Get thee a computer science degree! Michael Ash wrote: On Sat, Jul 12, 2008 at 1:24 PM, Marcel Weiher [EMAIL PROTECTED] wrote: No, the inline reference count is available for all CF objects, and not limited to 64 bit. What version of the structure are you looking at? For example http://www.cocoadev.com/index.pl?HowToCreateTollFreeBridgedClass shows this version, which matches what I got from opensource.apple.com I was looking at: http://www.opensource.apple.com/darwinsource/projects/apsl/CF-476.10/CFRuntime.h It defines: typedef struct __CFRuntimeBase { uintptr_t _cfisa; uint8_t _cfinfo[4]; #if __LP64__ uint32_t _rc; #endif } CFRuntimeBase; I guess this isn't the right one, then. To Gary, about 16-bit refcounts, I'd imagine that there's some logic in there where if you hit 0x, it considers that to be a flag to use an external refcount instead, at the cost of some speed. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
There are several ways to share the implementation: 1. Do nothing, CF and Foundation already do it for most of their objects (and they share their implementation...probably unreasonably...) This, obviously, doesn't work for your own classes. But a lot of the objects you will use will tend to be Foundation objects, especially if you've adopted the temp-object-heavy style. 2. Implement a common superclass This doesn't work if you're subclassing something other than NSObject already. Non-NSObject subclasses tend to be things like NSViews which are fairly heavy-weight and not that temporary. 3. Implement a function, inline function or macro that takes a pointer to the refcount ivar. This works, but still leaves you to copy/paste glue code everywhere. You don't even have to do that if you don't want to. Not every solution works in every context, but combined, they cover the bases rather well, making sharing the implementation quite easy. In my experience. [not referring to scanning overhead] - Temporary objects get a 'release' at the end of their life, and usually an 'autorelease' at the beginning. The cost of a single refcounting op is negligible compared to the cost of object allocation, so these two are quite irrelevant. - Jumping objects across the end of an autorelease pool by retaining them before destroying the pool. In my experience, this is rather rare, and the cost once again tends to be completely negligible compared to the cost of destroying the pool and the objects in the pool. - Paranoid or thread-safe accessors do a retain/autorelease dance before returning. This one is actually a problem. Don't do that, it isn't actually thread-safe and can cause at least as many problems as it 'solves'. Yes, just like objects don't get retained when they are stored in local variables, that happens when you store them into instance variables. They do get released though, which is a refcount operation that doesn't happen in the GC world. Once again, the -release is completely negligible compared to the actual deallocation. Taking into account the programming style a language supports is about as far from a micro-optimization as you can get. It is an architectural concern that informs how you structure your system, changing it after-the-fact often turns out to be impossible. At least that's been my experience over the last 20 years or so, YMMV. I'm not sure I understand what you're saying here. My point is that ObjC makes it very easy and natural to create temporary objects without worrying about their lifetimes. That is exactly my point: this is one case where the comparative ease is deceptive, as creating lots of temporary objects is not something that Objective-C supports well. Objective-C is a *hybrid* OO language, not a pure OO language. In my experience, code which goes to great lengths to avoid autoreleased objects is messy and much more bug prone than the normal way. Yes, if it is autoreleasing you avoid, not object creation in the first place. The extra autorelease only costs you maybe 30%, the extra object allocation costs you an order of magnitude or more. So for example, my standard pattern for initialization is something like this: -init { self=[super init]; [self setFoo:[Bar bar]]; return self; } Thus, yes, you can avoid many autoreleased objects if you want, but this is a painful micro optimization, not the standard way to do things. Once again, avoiding temporary object-creation is not a micro- optimization, and creating lots of temporary objects is definitely NOT the standard way to do things in Objective-C. You might have heard about the 80/20 rule, which is actually more a 90/10 or 95/05 rule: most of the execution time is spent in a very small portion of your code. Being able to go in and *really* optimize those hotspots actually gives you the most bang for the buck. The typical usage, meaning the bulk of the program, generally does not matter. I did my master's thesis on high performance code and optimization; I am more than vaguely familiar with these concepts. Glad to hear that! However, in the sections above you were continually treating ops that differ in cost by an order of magnitude or more with equal weight, which makes me somewhat dubious of your claimed credentials... My point is merely that GC can help you without you needing to change your code in any way. This, to me, is more valuable than peppering my code with lots of painful manual memory management to make it go faster. ...as does this. Once again: this is not about randomly peppering code with lots of painful manual memory management, this is about (a) adopting a coding style that is clean, (b) flows with what Objective-C provides and is good at and (c) allows for the highly focused optimizations that actually make an
Re: garbage collection and NSConnection
On Jul 11, 2008, at 8:59 , Michael Ash wrote: The cost of a single refcounting op is negligible compared to the cost of object allocation, so these two are quite irrelevant. A quick test of this claim would appear to disprove it. On my Mac Pro, an alloc/init/release cycle of NSObject costs about 290ns. Adding an extra pair of retain/release costs about 480ns. I'm not sure how I can reasonably measure the object allocation by itself, or the cost of just retain or just release. But it seems clear that these refcounting operations are quite significant in cost. This is the extra refcount table in action, and why inline reference counts can be such a performance win on objects that are frequently retained and released. Changing the object to an NSString (which has an internal reference count) yields the following results on my MacBook Pro: retain+release NSString: time per iteration: 67 nanoseconds Compare this with the times for NSObject, both retain/release and allocation / deallocation: retain+release NSObject 2-3 / 3-2 : time per iteration: 223 nanoseconds retain+release NSObject 1-2 / 2-1 : time per iteration: 276 nanoseconds alloc+dealloc NSObject: time per iteration: 415 nanoseconds Cheers, Marcel [EOT for me] [Differences of opinion and experience snipped] ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Fri, Jul 11, 2008 at 2:17 PM, Marcel Weiher [EMAIL PROTECTED] wrote: On Jul 11, 2008, at 8:59 , Michael Ash wrote: The cost of a single refcounting op is negligible compared to the cost of object allocation, so these two are quite irrelevant. A quick test of this claim would appear to disprove it. On my Mac Pro, an alloc/init/release cycle of NSObject costs about 290ns. Adding an extra pair of retain/release costs about 480ns. I'm not sure how I can reasonably measure the object allocation by itself, or the cost of just retain or just release. But it seems clear that these refcounting operations are quite significant in cost. This is the extra refcount table in action, and why inline reference counts can be such a performance win on objects that are frequently retained and released. Changing the object to an NSString (which has an internal reference count) yields the following results on my MacBook Pro: retain+release NSString: time per iteration: 67 nanoseconds Compare this with the times for NSObject, both retain/release and allocation / deallocation: retain+release NSObject 2-3 / 3-2 : time per iteration: 223 nanoseconds retain+release NSObject 1-2 / 2-1 : time per iteration: 276 nanoseconds alloc+dealloc NSObject: time per iteration: 415 nanoseconds Seems that NSString and NSMutableString are just faster at everything. In all cases, the cost of an extra retain/release for them is still roughly 50% of the cost of an alloc/init/retain. Here are my raw numbers, times in nanoseconds: NSObject alloc/init/release 284.3 NSObject alloc/init/retain/release/release 495.7 Extra time taken: 74% NSString alloc/init/release 40.2 NSString alloc/init/retain/release/release 73.4 Extra time taken: 45% NSMutableString alloc/init/release 194.7 NSMutableString alloc/init/retain/release/release 300.7 Extra time taken: 54% I have no explanation as to why NSMutableString is so much slower at everything. They both end up creating an instance of NSCFString, so this is puzzling. But there you are. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
Some minor factual corrections: On Jul 2, 2008, at 18:33 , Michael Ash wrote: In Cocoa you do lots of retaining and releasing. These operations aren't free. They involve a lookup into a global hash table and some sort of atomic increment/decrement operation. The hash table is only used by NSObject subclasses that do not implement their own inline reference count. Most Foundation objects do implement such an inline reference count, so there are no hash lookups involved, just the atomic increment/decrement. I would strongly recommend that you implement an inline reference count for your own objects if they undergo frequent ownership changes. They're pretty fast, but there's certainly some cost there. Garbage collection lets you eliminate all of this code, so you get a speed bonus there. GC does not eliminate this overhead, it replaces it with the overhead of the write-barrier functions that are called when you do an assignment. These calls are generated automatically by the compiler, so you don't see them in your code, but they are still function calls. This is in addition to the scanning overhead. The question of memory usage is far from a given, especially in Cocoa where you do lots of autoreleasing. The pervasive use of autorelease essentially means that objects don't go away until you go back to the event loop. They generally go away whenever you want them to go away. The top of the event loop is a good default, but it is just that: a convenient default. This can result in large spikes in memory usage during event processing. If you see such spikes, simply add autorelease pools to your processing. Also: don't gratuitously create and/or autorelease objects if you don't have to. Objective-C object-creation is pretty heavy-weight compared to other OO languages, regardless of wether you are using garbage collection or reference counting, so programming- styles that do a lot of object-creation will suffer, performance-wise. With RC, there are ways to mitigate the effects ( see http://www.metaobject.com/blog/2007/08/high-performance-objective-c-i.html and http://www.metaobject.com/blog/2007/09/more-on-mpwobjectcache.html ), whereas I haven't yet found a way to achieve the same effect with GC. The collector isn't constrained by the event loop and can run any time it wants to, so it can potentially prevent these spikes from occurring. This also has a performance impact, as a more memory efficient program is also a faster program due to having a smaller working set. You can achieve the same effect by inserting autorelease pools during processing. Cocoa's GC also has another interesting advantage: most of the work is done on a background thread. This means that on any multi-core machine (which is any Mac sold in the past couple of years) that isn't already loaded at 100%, this bulk of the GC work essentially comes for free. ...as does doing the work during the top of the event loop when the machine is waiting for user input. Of course free is actually not free (a) in terms of power consumption and (b) in terms of memory bandwidth, which is a shared resource between the cores and frequently the bottleneck these days and (c) if you have other work for that core. Cheers, Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Thu, Jul 10, 2008 at 12:17 PM, Marcel Weiher [EMAIL PROTECTED] wrote: Some minor factual corrections: On Jul 2, 2008, at 18:33 , Michael Ash wrote: In Cocoa you do lots of retaining and releasing. These operations aren't free. They involve a lookup into a global hash table and some sort of atomic increment/decrement operation. The hash table is only used by NSObject subclasses that do not implement their own inline reference count. Most Foundation objects do implement such an inline reference count, so there are no hash lookups involved, just the atomic increment/decrement. I would strongly recommend that you implement an inline reference count for your own objects if they undergo frequent ownership changes. Atomic updates are still a pretty big hit on a multiprocessor system (all of them, these days), and implementing your own is a fair amount of work that you simply don't have to do in a GC environment. Especially since you can't reasonably implement it once and share the implementation, you'll have to manually insert the implementation into your classes individually. They're pretty fast, but there's certainly some cost there. Garbage collection lets you eliminate all of this code, so you get a speed bonus there. GC does not eliminate this overhead, it replaces it with the overhead of the write-barrier functions that are called when you do an assignment. These calls are generated automatically by the compiler, so you don't see them in your code, but they are still function calls. This is in addition to the scanning overhead. No, it *does* eliminate this overhead, and it has this *other* overhead. It's not a replacement, because the overheads are not identical, neither in time nor in location. For example, in the very common scenario of creating temporary objects which never leave the stack, a write barrier is never generated. The question of memory usage is far from a given, especially in Cocoa where you do lots of autoreleasing. The pervasive use of autorelease essentially means that objects don't go away until you go back to the event loop. They generally go away whenever you want them to go away. The top of the event loop is a good default, but it is just that: a convenient default. This can result in large spikes in memory usage during event processing. If you see such spikes, simply add autorelease pools to your processing. Yet more work that you don't have to do in a GC system. And autorelease pools, while quite cheap, are not free. Also: don't gratuitously create and/or autorelease objects if you don't have to. Objective-C object-creation is pretty heavy-weight compared to other OO languages, regardless of wether you are using garbage collection or reference counting, so programming-styles that do a lot of object-creation will suffer, performance-wise. You can bend your programming style to micro-optimize the language's speed if you want, but that's not the kind of thing I prefer to do. I'd rather look at how GC compares to refcounting in typical usage, not this kind of carefully optimized usage that rarely happens. Cocoa's GC also has another interesting advantage: most of the work is done on a background thread. This means that on any multi-core machine (which is any Mac sold in the past couple of years) that isn't already loaded at 100%, this bulk of the GC work essentially comes for free. ...as does doing the work during the top of the event loop when the machine is waiting for user input. This doesn't work when you're compute bound, which is of course the only time that performance actually matters anyway. Of course free is actually not free (a) in terms of power consumption and (b) in terms of memory bandwidth, which is a shared resource between the cores and frequently the bottleneck these days and (c) if you have other work for that core. That would be why I put it into quotes. The point being that while it's not really free, it takes no additional wall-clock time in the common case. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Jul 10, 2008, at 9:50 , Michael Ash wrote: On Thu, Jul 10, 2008 at 12:17 PM, Marcel Weiher [EMAIL PROTECTED] wrote: [hash tables not generally used + internal refcounts] Atomic updates are still a pretty big hit on a multiprocessor system (all of them, these days), Yes, they're definitely not free. and implementing your own is a fair amount of work that you simply don't have to do in a GC environment. Not really, no. Especially since you can't reasonably implement it once and share the implementation, you'll have to manually insert the implementation into your classes individually. There are several ways to share the implementation: 1. Do nothing, CF and Foundation already do it for most of their objects (and they share their implementation...probably unreasonably...) 2. Implement a common superclass 3. Implement a function, inline function or macro that takes a pointer to the refcount ivar. They're pretty fast, but there's certainly some cost there. Garbage collection lets you eliminate all of this code, so you get a speed bonus there. GC does not eliminate this overhead, it replaces it with the overhead of the write-barrier functions that are called when you do an assignment. These calls are generated automatically by the compiler, so you don't see them in your code, but they are still function calls. This is in addition to the scanning overhead. It's not a replacement, because the overheads are not identical, neither in time nor in location. Why do you say that? The write barrier code gets called when when you store an object into an instance variable, same as for a retain. They are actually at pretty much precisely the same time and location. I am guessing you are referring to the scanning overhead, about which you are right: it happens at a different time and in a different place, and in addition to the checks. For example, in the very common scenario of creating temporary objects which never leave the stack, a write barrier is never generated. Yes, just like objects don't get retained when they are stored in local variables, that happens when you store them into instance variables. Also: don't gratuitously create and/or autorelease objects if you don't have to. Objective-C object-creation is pretty heavy-weight compared to other OO languages, regardless of wether you are using garbage collection or reference counting, so programming-styles that do a lot of object- creation will suffer, performance-wise. You can bend your programming style to micro-optimize the language's speed if you want, but that's not the kind of thing I prefer to do. Taking into account the programming style a language supports is about as far from a micro-optimization as you can get. It is an architectural concern that informs how you structure your system, changing it after-the-fact often turns out to be impossible. At least that's been my experience over the last 20 years or so, YMMV. I'd rather look at how GC compares to refcounting in typical usage, not this kind of carefully optimized usage that rarely happens. You might have heard about the 80/20 rule, which is actually more a 90/10 or 95/05 rule: most of the execution time is spent in a very small portion of your code. Being able to go in and *really* optimize those hotspots actually gives you the most bang for the buck. The typical usage, meaning the bulk of the program, generally does not matter. This is one of those areas where Objective-C really, really excels: the ability to combine very high-level, very abstracted code with small bits of highly optimized code to get an optimum balance of expressiveness and performance. ...as does doing the work during the top of the event loop when the machine is waiting for user input. This doesn't work when you're compute bound, which is of course the only time that performance actually matters anyway. The latter part is only true iff your apps do not need to responsive. I prefer apps that are. The first part is where that 95/5 rule comes in and being able to tune those hotspots really comes in handy. Cheers, Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Thu, Jul 10, 2008 at 7:33 PM, Marcel Weiher [EMAIL PROTECTED] wrote: On Jul 10, 2008, at 9:50 , Michael Ash wrote: On Thu, Jul 10, 2008 at 12:17 PM, Marcel Weiher [EMAIL PROTECTED] wrote: [hash tables not generally used + internal refcounts] Atomic updates are still a pretty big hit on a multiprocessor system (all of them, these days), Yes, they're definitely not free. and implementing your own is a fair amount of work that you simply don't have to do in a GC environment. Not really, no. Especially since you can't reasonably implement it once and share the implementation, you'll have to manually insert the implementation into your classes individually. There are several ways to share the implementation: 1. Do nothing, CF and Foundation already do it for most of their objects (and they share their implementation...probably unreasonably...) This, obviously, doesn't work for your own classes. 2. Implement a common superclass This doesn't work if you're subclassing something other than NSObject already. 3. Implement a function, inline function or macro that takes a pointer to the refcount ivar. This works, but still leaves you to copy/paste glue code everywhere. They're pretty fast, but there's certainly some cost there. Garbage collection lets you eliminate all of this code, so you get a speed bonus there. GC does not eliminate this overhead, it replaces it with the overhead of the write-barrier functions that are called when you do an assignment. These calls are generated automatically by the compiler, so you don't see them in your code, but they are still function calls. This is in addition to the scanning overhead. It's not a replacement, because the overheads are not identical, neither in time nor in location. Why do you say that? The write barrier code gets called when when you store an object into an instance variable, same as for a retain. They are actually at pretty much precisely the same time and location. I am guessing you are referring to the scanning overhead, about which you are right: it happens at a different time and in a different place, and in addition to the checks. I'm not referring to the scanning overhead. There are many scenarios where a refcount modification is made which do not produce a write barrier in GC-land. For example: - Temporary objects get a 'release' at the end of their life, and usually an 'autorelease' at the beginning. - Paranoid or thread-safe accessors do a retain/autorelease dance before returning. - Jumping objects across the end of an autorelease pool by retaining them before destroying the pool. For example, in the very common scenario of creating temporary objects which never leave the stack, a write barrier is never generated. Yes, just like objects don't get retained when they are stored in local variables, that happens when you store them into instance variables. They do get released though, which is a refcount operation that doesn't happen in the GC world. Also: don't gratuitously create and/or autorelease objects if you don't have to. Objective-C object-creation is pretty heavy-weight compared to other OO languages, regardless of wether you are using garbage collection or reference counting, so programming-styles that do a lot of object-creation will suffer, performance-wise. You can bend your programming style to micro-optimize the language's speed if you want, but that's not the kind of thing I prefer to do. Taking into account the programming style a language supports is about as far from a micro-optimization as you can get. It is an architectural concern that informs how you structure your system, changing it after-the-fact often turns out to be impossible. At least that's been my experience over the last 20 years or so, YMMV. I'm not sure I understand what you're saying here. My point is that ObjC makes it very easy and natural to create temporary objects without worrying about their lifetimes. In my experience, code which goes to great lengths to avoid autoreleased objects is messy and much more bug prone than the normal way. Thus, yes, you can avoid many autoreleased objects if you want, but this is a painful micro optimization, not the standard way to do things. I'd rather look at how GC compares to refcounting in typical usage, not this kind of carefully optimized usage that rarely happens. You might have heard about the 80/20 rule, which is actually more a 90/10 or 95/05 rule: most of the execution time is spent in a very small portion of your code. Being able to go in and *really* optimize those hotspots actually gives you the most bang for the buck. The typical usage, meaning the bulk of the program, generally does not matter. I did my master's thesis on high performance code and optimization; I am more than vaguely familiar with these concepts. My point is merely that GC can help you without you needing to change
Re: garbage collection and NSConnection
El 07/07/2008, a las 0:18, Hamish Allan escribió: On 7/4/08, Chris Hanson [EMAIL PROTECTED] wrote: Under non-GC, an object's memory may not be reclaimed until the current autorelease pool is drained. However, under GC, an object's memory can be reclaimed as soon as the collector can tell there are no more references to it -- no matter when that is. I think Joan's point is not that there are circumstances in which the GC will never reclaim, but that it is not possible to ensure reclamation deterministically. [...] Collection is subject to interruption on user input -- with no mention of when it might be re-started. Hamish Thanks Hamish. That was exactly my point, and that citation of the documentation gives more plausibility to it. (my native language is not English, nor I live in an English speaking country so it can be sometimes difficult for me to express complex things or to know the more appropriate word to express a concept, this is why I tend to paraphrase on my writing, and I understand that it can be difficult to read). Joan Lluch ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On 7/6/08 11:18 PM, Hamish Allan said: collectExhaustively Tells the receiver to collect iteratively. - (void)collectExhaustively Discussion You use this method to indicate to the collector that it should perform an exhaustive collection. Collection is subject to interruption on user input. Availability Available in Mac OS X v10.5 and later. Declared In NSGarbageCollector.h Collection is subject to interruption on user input -- with no mention of when it might be re-started. There's always the lower-level: objc_collect (OBJC_EXHAUSTIVE_COLLECTION | OBJC_WAIT_UNTIL_DONE); -- Sean McBride, B. Eng [EMAIL PROTECTED] Rogue Researchwww.rogue-research.com Mac Software Developer Montréal, Québec, Canada ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Mon, Jul 7, 2008 at 6:33 PM, Sean McBride [EMAIL PROTECTED] wrote: There's always the lower-level: objc_collect (OBJC_EXHAUSTIVE_COLLECTION | OBJC_WAIT_UNTIL_DONE); If this were called from the main thread, would it guarantee that the collector run without interruption, given that user input would be suspended? Otherwise, there's still rather a difference between do and wait until done... Hamish ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
El 06/07/2008, a las 2:05, mmalc crawford escribió: On Jul 5, 2008, at 3:00 PM, Joan Lluch (casa) wrote: However, let me copy an excerpt of the Cocoa documentation on the GC algorithm that Cocoa uses. You haven't updated your documentation since the beginning of November last year. Oops, thanks. Looks as it is time for me to update things... I will give the Cocoa GC another try before adding another comment, (my apologies, I might be testing an earlier version) By the way, how do I know for sure that a set of documentation corresponds to a particular version of the SKD. I am using XCode 3.0 for mac development since I believe it is the latest non pre-release version of the dev-tools and the documentation files that came with it. Is 3.1 already intended for use for mac development?. Since this post will go out of topic I am also posting this on the Xcode lists, where I think I should receive a more appropriate answer. Joan Lluch___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On 7/4/08, Chris Hanson [EMAIL PROTECTED] wrote: Under non-GC, an object's memory may not be reclaimed until the current autorelease pool is drained. However, under GC, an object's memory can be reclaimed as soon as the collector can tell there are no more references to it -- no matter when that is. I think Joan's point is not that there are circumstances in which the GC will never reclaim, but that it is not possible to ensure reclamation deterministically. From the docs: collectExhaustively Tells the receiver to collect iteratively. - (void)collectExhaustively Discussion You use this method to indicate to the collector that it should perform an exhaustive collection. Collection is subject to interruption on user input. Availability Available in Mac OS X v10.5 and later. Declared In NSGarbageCollector.h Collection is subject to interruption on user input -- with no mention of when it might be re-started. Hamish ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Jul 5, 2008, at 3:00 PM, Joan Lluch (casa) wrote: However, let me copy an excerpt of the Cocoa documentation on the GC algorithm that Cocoa uses. You haven't updated your documentation since the beginning of November last year. begin excerpt [...] The collector runs exclusively on the main thread of the application. At no time are all threads stopped for a collection cycle, and each thread is stopped for as short a time as is possible. Threads may be blocked for a short time while all unreachable objects are formed into the garbage list and weak references zeroed. Only threads that have directly or indirectly performed an[NSThread self] operation are subject to garbage collection. This is not correct for the current implementation of the collector: The collector is both request and demand driven. The Cocoa implementation makes requests at appropriate times. You can also programmatically request consideration of a garbage collection cycle, and if a memory threshold has been exceeded a collection is run automatically. The collector runs on its own thread in the application. At no time are all threads stopped for a collection cycle, and each thread is stopped for as short a time as is possible. It is possible for threads requesting collector actions to block during a critical section on the collector thread's part. Only threads that have directly or indirectly performed an [NSThread self] operation are subject to garbage collection. The collector is generational (see “Write Barriers”)—most collections are very fast and recover significant amounts of recently-allocated memory, but not all possible memory. Full collections are also fast and do collect all possible memory, but are run less frequently, at times unlikely to impact user event processing, and may be aborted in the presence of new user events. http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcArchitecture.html mmalc ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Jul 5, 2008, at 3:00 PM, Joan Lluch (casa) wrote: Basically for performance reasons, the G. collector preffers to let memory usage grow (while it is still available) in order to avoid too many collections or to try that the user does not notice it, and in practice it generally succeeds at it. But you will definitely notice some annoying sporadic app response delays of half a second or so specially if your app is very complex and maintains lots of objects referencing each other in complex graphs. Only if some of those objects force the main thread to block (which can happen as certain objects do require finalization on the main thread -- these are considered to be bugs and will be eliminated as time permits) or if you have written classes with complex finalizers that cause your secondary threads to block. And it isn't that the collector prefers to let memory usage grow. More so that the collector strives to achieve a balance between memory use, responsiveness, and CPU cycles consumed, with user responsiveness being the most heavily weighted of the three. If there are ways for the collector to collect more efficiently without impacting user responsiveness, said ways will be implemented b.bum smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
El 04/07/2008, a las 11:38, Jean-Daniel Dupas escribió: I don't see your point. Using standard memory management, you can create you own pool, and using GC, you can manually trigger the GC. What prevent you to avoid memory peak ? Bonjour, Jean. Try it yourself. With the correct use of an autorelease pool you can turn a simple loop to hog all memory resources to not use any perceivable amount of memory. It is exactly as this because it was designed this way. However, this is hardly possible with GC even if you trigger the GC manually in the middle of the loop. It simply will not release the memory at the rate you expect because it follows its own rules and as far as free memory is available it will not free anything unless it is a reason, according to its algorithms, to do so. Furthermore, the fact that the memory is released in a parallel threat running at lower priority, allows for little chance that the memory you would like to be released at a particular point, actually gets released on time. When things go really bad, the GC simply stops the app (in a user noticeable way) until it has been able to free enough resources for the app to continue. I might add that I really hate this, and this is why I turned back to retain/release in my Cocoa development. Look at it the way you want, but you simply won't have control of the memory resources used by your app in a GC environment. Just keep a look at Activity Monitor and compare the memory usage of similarly complex apps, running on GC and not. Usually the difference is huge. On the other hand, a badly designed normal application can eventually consume a lot more than a GC enabled app. But my point is that you *can* control it and you can keep it down, however you *can't* in a GC App. My point is also that it is not *that* hard to deal manually with your app resources given the clever release/ autorelelase/retain features of Cocoa. However, it is true that GC will always keep global memory usage in control (in all cases), and will never crash the app for that reason, because it is obviously designed to do so. You cannot compare iPhone with a desktop/laptop computer. That's not the only facility Apple has disabled on the iPhone for optimization, and that does not mean that all thoses features sucks. Agreed, the iPhone is tiny compared to a desktop computer, and as you already concede, several features have had to be disabled to keep with performance requirements. However I didn't want to imply that GC does suck, It is already a matured technology used by virtually all modern languages, which can't even be disabled in most of them, and therefore it is here to stay, and certainly a needed improvement to Cocoa programming in order to keep with the latest development trends. Joan Lluch (casa) ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Jul 4, 2008, at 2:25 AM, Joan Lluch (casa) wrote: First, GC makes programs go slower not because of the overhead of the garbage collection itself, which I concede that may be comparable to the retain/release calls in a non-managed environment, but for the extra memory overhead that it is used. The crucial difference between a non-managed app and a GC app is that in a non- managed app the memory is released very soon after the life of an object has expired. Please do not spread misinformation about Objective-C garbage collection. What you're essentially asserting is that Objective-C garbage collection will always increase the high-water mark of an application, and that is not the case. Memory in a GC app is released very soon after the life of an object is over -- sometimes, even sooner than it would be under manual memory management. That's because Objective-C garbage collection runs on a separate thread. Under non-GC, an object's memory may not be reclaimed until the current autorelease pool is drained. However, under GC, an object's memory can be reclaimed as soon as the collector can tell there are no more references to it -- no matter when that is. -- Chris ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Jul 4, 2008, at 9:32 AM, Joan Lluch (casa) wrote: However, this is hardly possible with GC even if you trigger the GC manually in the middle of the loop. It simply will not release the memory at the rate you expect because it follows its own rules and as far as free memory is available it will not free anything unless it is a reason, according to its algorithms, to do so. This situation should work. If it does not, that's something to report to Apple via the bug reporter http://bugreport.apple.com/ and, if possible attach a test case that demonstrates the issue. Do not assume that it's simply the collector follow[ing] its own rules. The collector should -- and DOES -- collect objects that it can tell are no longer referenced. In fact, we've had occasional threads here about objects used at the beginning of a method being collected while interior pointers that they've handed out are still in use, so it's not just hypothetical. -- Chris ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
El 30/06/2008, a las 19:33, [EMAIL PROTECTED] escribió: hey, I have a project that uses Bonjour for some of its communication, theres a server and a client, and I was having tremendous difficulty getting it to work, pouring and pouring over my code, only to discover some weeks later that for some odd reason, NSConnections do not work when the project is set to support or require garbage collection. As a test I set garbage collection to: Unsupported, and the app compiled, and the NSConnection returned the proxy object as expected. But the app obviously failed to do much else, because I had no retain, release, or autorelease method calls. I am not a lazy person, but I am a novice programmer, and the retain, release, autorelease stuff in cocoa is horrible. I was very happy when garbage collection was added to Cocoa, and my projects became much easier to develop, and maintain. Now however, I find myself with a project riddled with memory problems that did Not exist just a few days ago, and as far as I can tell, I don't have any choice... My app either gives up Bonjour, or I have to retrofit the whole thing to manage its own memory with a system that is, lets face it, poorly envisioned. can anybody shed any light on this? am I really stuck managing the memory myself? This is intolerable. cheers, -eblu ___ Well, it always takes a risk to embrace a technology that is just released, such as garbage collection. Cocoa APIs and the Objective-C language was not designed from its origins with garbage collection in mind, so it must have been a really tedious and bug prone process for Apple to convert all the frameworks to properly work in a managed memory context. This is unlike Java and C#, which have been created from the beginning with such feature. In any case, Garbage collection is neither good or bad, it certainly allows you to not have to care about Zombies and Leaks, but you will still have to think about the lifetime of objects. You will still have to remove observers, or unbind objects, and think that your objects will be eventually reclaimed by the garbage collector, in an undefined order, so you will have to implement finalize methods. From my experience, at the end of the day, coding in a garbage collected environment, is not such a better deal. Obj-C, unlike C++, has a very clean way to deal with memory: the release/autorelease/ retain way to manage your memory, along with autorelease pools, and the consistence of the Cocoa APIs with respect to returned objects, are heaven compared to what you have to implement in C++, or other not managed memory languages. Basically, all you have to do is to always return autoreleased objects from your methods, and always send release to objects that you created with alloc or were returned by any method containing new or copy. Also, if you only use the standard accessor methods for setting properties, (which send release to the old object and retain the new one), you will not incur in any memory problem. It should not be that hard, and at the end your application will potentially perform better, and for sure it will eat significantly less memory. Joan Lluch. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Wed, Jul 2, 2008 at 6:09 PM, Joan Lluch (casa) [EMAIL PROTECTED] wrote: Basically, all you have to do is to always return autoreleased objects from your methods, and always send release to objects that you created with alloc or were returned by any method containing new or copy. Also, if you only use the standard accessor methods for setting properties, (which send release to the old object and retain the new one), you will not incur in any memory problem. It should not be that hard, and at the end your application will potentially perform better, and for sure it will eat significantly less memory. I have to object to this bit at the end. It's a common cliche that garbage collection makes your program perform worse and use more memory. And certainly this is *possible*. But it's far from a given these days. In Cocoa you do lots of retaining and releasing. These operations aren't free. They involve a lookup into a global hash table and some sort of atomic increment/decrement operation. They're pretty fast, but there's certainly some cost there. Garbage collection lets you eliminate all of this code, so you get a speed bonus there. Whether this is overcome by the overhead that GC gives you will depend on the specific program. The question of memory usage is far from a given, especially in Cocoa where you do lots of autoreleasing. The pervasive use of autorelease essentially means that objects don't go away until you go back to the event loop. This can result in large spikes in memory usage during event processing. The collector isn't constrained by the event loop and can run any time it wants to, so it can potentially prevent these spikes from occurring. This also has a performance impact, as a more memory efficient program is also a faster program due to having a smaller working set. Cocoa's GC also has another interesting advantage: most of the work is done on a background thread. This means that on any multi-core machine (which is any Mac sold in the past couple of years) that isn't already loaded at 100%, this bulk of the GC work essentially comes for free. Now, this is not to say that GC will make your program go faster. This will depend greatly on exactly how your program is designed and implemented. But while GC won't automatically make your program go faster, it also won't automatically make it go slower. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
Hi there- I encountered the same issue some months ago, and posted my questions to this list. An Apple engineer did reply off-list that this was a known issue with garbage collection and that there was no known workaround at that time. I was just playing with GC for fun and reverted back to regular memory management. You might inquire of Apple DTS if things have changed at all; my incident was in the 10.5.0 days. John John Pannell http://www.positivespinmedia.com On Jun 30, 2008, at 11:33 AM, [EMAIL PROTECTED] wrote: hey, I have a project that uses Bonjour for some of its communication, theres a server and a client, and I was having tremendous difficulty getting it to work, pouring and pouring over my code, only to discover some weeks later that for some odd reason, NSConnections do not work when the project is set to support or require garbage collection. As a test I set garbage collection to: Unsupported, and the app compiled, and the NSConnection returned the proxy object as expected. But the app obviously failed to do much else, because I had no retain, release, or autorelease method calls. can anybody shed any light on this? am I really stuck managing the memory myself? This is intolerable. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
Hi Chris, I'm not terribly sure what you are asking for here. From my experience (limited experience admittedly) theres really only one way to use NSConnection. its a pretty elegant class, which is simple, and works as expected, except for when garbage collection is enabled. heres what I do just after NSNetService finds a service: // Sent when a service appears - (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing { NSMutableDictionary* newDict = [[NSMutableDictionary alloc] init]; [newDict setValue:aNetService forKey:@theService]; [serverArrayController addObject:newDict]; [aNetService setDelegate:self]; [aNetService resolveWithTimeout:5]; if(!moreComing) { } } // NSNetService Delegate method: - (void)netServiceDidResolveAddress:(NSNetService *)sender{ id proxy = nil; NSData *addy; NSSocketPort* socket; NSConnection* connection; NSString* hostname; int a; int i; hostname = [sender hostName]; socket = (NSSocketPort*)[[NSSocketPortNameServer sharedInstance] portForName:@BKOtherPort host:hostname]; connection = [NSConnection connectionWithReceivePort: nil sendPort: socket]; @try{ proxy = [connection rootProxy]; } @catch(id exception){ proxy = nil; } addy = [socket address]; if(proxy){ // app level stuff if the proxy exists } } pretty straight forward, and every time I ran it with garbage collection on, the NSConnection initialized, but NEVER returned the proxy. it returned nil. all my instance variables were populated, everything on My end was correct... or at least behaving as expected. it just wouldn't return the proxy object (or the root for that matter) All I did to fix it, was to turn off garbage collection. That part runs like a champ now. the rest of the app won't do anything anymore, as it was built on garbage collection. cheers, -eb On Jun 30, 2008, at 3:37 PM, Chris Hanson wrote: On Jun 30, 2008, at 10:33 AM, [EMAIL PROTECTED] wrote: only to discover some weeks later that for some odd reason, NSConnections do not work when the project is set to support or require garbage collection. How are you using NSConnection? NSConnection and Distributed Objects definitely *does* work with Objective-C garbage collection, at least in the situations in which I've used it. Some code examples might be illustrative. -- Chris ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
Le 30 juin 08 à 22:10, eblu a écrit : Hi Chris, I'm not terribly sure what you are asking for here. From my experience (limited experience admittedly) theres really only one way to use NSConnection. its a pretty elegant class, which is simple, and works as expected, except for when garbage collection is enabled. heres what I do just after NSNetService finds a service: // Sent when a service appears - (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing { NSMutableDictionary* newDict = [[NSMutableDictionary alloc] init]; [newDict setValue:aNetService forKey:@theService]; [serverArrayController addObject:newDict]; [aNetService setDelegate:self]; [aNetService resolveWithTimeout:5]; if(!moreComing) { } } // NSNetService Delegate method: - (void)netServiceDidResolveAddress:(NSNetService *)sender{ id proxy = nil; NSData *addy; NSSocketPort* socket; NSConnection* connection; NSString* hostname; int a; int i; hostname = [sender hostName]; socket = (NSSocketPort*)[[NSSocketPortNameServer sharedInstance] portForName:@BKOtherPort host:hostname]; connection = [NSConnection connectionWithReceivePort: nil sendPort: socket]; @try{ proxy = [connection rootProxy]; } @catch(id exception){ proxy = nil; } addy = [socket address]; if(proxy){ // app level stuff if the proxy exists } } pretty straight forward, and every time I ran it with garbage collection on, the NSConnection initialized, but NEVER returned the proxy. it returned nil. all my instance variables were populated, everything on My end was correct... or at least behaving as expected. it just wouldn't return the proxy object (or the root for that matter) All I did to fix it, was to turn off garbage collection. That part runs like a champ now. the rest of the app won't do anything anymore, as it was built on garbage collection. cheers, -eb And did you try using CFNetServices instead ? As it is CF based, it probably does not have the same GC problem and is it far more easier to replace NSNetService by CFNetService than rewriting the whole application without GC . smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
Le 30 juin 08 à 22:19, Jean-Daniel Dupas a écrit : Le 30 juin 08 à 22:10, eblu a écrit : Hi Chris, I'm not terribly sure what you are asking for here. From my experience (limited experience admittedly) theres really only one way to use NSConnection. its a pretty elegant class, which is simple, and works as expected, except for when garbage collection is enabled. heres what I do just after NSNetService finds a service: // Sent when a service appears - (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing { NSMutableDictionary* newDict = [[NSMutableDictionary alloc] init]; [newDict setValue:aNetService forKey:@theService]; [serverArrayController addObject:newDict]; [aNetService setDelegate:self]; [aNetService resolveWithTimeout:5]; if(!moreComing) { } } // NSNetService Delegate method: - (void)netServiceDidResolveAddress:(NSNetService *)sender{ id proxy = nil; NSData *addy; NSSocketPort* socket; NSConnection* connection; NSString* hostname; int a; int i; hostname = [sender hostName]; socket = (NSSocketPort*)[[NSSocketPortNameServer sharedInstance] portForName:@BKOtherPort host:hostname]; connection = [NSConnection connectionWithReceivePort: nil sendPort: socket]; @try{ proxy = [connection rootProxy]; } @catch(id exception){ proxy = nil; } addy = [socket address]; if(proxy){ // app level stuff if the proxy exists } } pretty straight forward, and every time I ran it with garbage collection on, the NSConnection initialized, but NEVER returned the proxy. it returned nil. all my instance variables were populated, everything on My end was correct... or at least behaving as expected. it just wouldn't return the proxy object (or the root for that matter) All I did to fix it, was to turn off garbage collection. That part runs like a champ now. the rest of the app won't do anything anymore, as it was built on garbage collection. cheers, -eb And did you try using CFNetServices instead ? As it is CF based, it probably does not have the same GC problem and is it far more easier to replace NSNetService by CFNetService than rewriting the whole application without GC . Sorry, it the DO part that does not works, not the Bonjour discovery. I read it a little to fast. smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]
Re: garbage collection and NSConnection
On Mon, Jun 30, 2008 at 9:10 PM, eblu [EMAIL PROTECTED] wrote: hostname = [sender hostName]; socket = (NSSocketPort*)[[NSSocketPortNameServer sharedInstance] portForName:@BKOtherPort host:hostname]; connection = [NSConnection connectionWithReceivePort: nil sendPort: socket]; @try{ proxy = [connection rootProxy]; } Have you tried the rather more simple: proxy = [[NSConnection rootProxyForConnectionWithRegisteredName:@BKOtherPort host:[sender hostname]] retain]; ? Hamish ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]