Re: garbage collection and NSConnection

2008-07-13 Thread Marcel Weiher


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

2008-07-13 Thread Michael Ash
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

2008-07-12 Thread Marcel Weiher


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

2008-07-12 Thread Gary L. Wade

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

2008-07-12 Thread Michael Ash
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

2008-07-12 Thread Gary L. Wade
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

2008-07-11 Thread Marcel Weiher

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

2008-07-11 Thread Marcel Weiher


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

2008-07-11 Thread Michael Ash
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

2008-07-10 Thread Marcel Weiher

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

2008-07-10 Thread Michael Ash
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

2008-07-10 Thread Marcel Weiher


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

2008-07-10 Thread Michael Ash
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

2008-07-07 Thread Joan Lluch (casa)


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

2008-07-07 Thread Sean McBride
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

2008-07-07 Thread Hamish Allan
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

2008-07-06 Thread Joan Lluch (casa)


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

2008-07-06 Thread Hamish Allan
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

2008-07-05 Thread mmalc crawford


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

2008-07-05 Thread Bill Bumgarner

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

2008-07-04 Thread casa


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

2008-07-04 Thread Chris Hanson

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

2008-07-04 Thread Chris Hanson

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

2008-07-02 Thread Joan Lluch (casa)


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

2008-07-02 Thread Michael Ash
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]


garbage collection and NSConnection

2008-06-30 Thread eblugamma

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
___

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

2008-06-30 Thread John Pannell

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

2008-06-30 Thread eblu

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

2008-06-30 Thread Jean-Daniel Dupas

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

2008-06-30 Thread Jean-Daniel Dupas


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

2008-06-30 Thread Hamish Allan
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]