Re: Adding an associated reference is memory expensive (was: Adding an observer is memory expensive)
Re: Adding an associated reference is memory expensive (was: Adding an observer is memory expensive)
- Subject: Re: Adding an associated reference is memory expensive (was: Adding an observer is memory expensive)
- From: Kai BrĂ¼ning <email@hidden>
- Date: Sat, 12 Sep 2009 09:59:48 +0200
On 12.9.2009, at 00:35, Greg Parker wrote:
We have your earlier report rdar://7212101. Thanks, Torsten. (Ken
didn't see it because the bug didn't pass through his group's hands
on its way to my group.)
This is a bug in the associated reference machinery. That code keeps
a C++ std::hash_map per augmented object, mapping associated keys to
associated values. std::hash_map uses an std::vector internally, and
the default hash_map constructor pre-allocates 100 entries for that
vector.
Which are then raised to 193 by __stl_next_prime() in hashtable.h.
Times the 64 bit pointer size makes 1544 bytes, which GC seems to
round up to the 2k seen by the OP.
This is overkill for associated objects usage. The fix is to use a
non-default constructor that specifies a much smaller initial
hash_map size.
Unfortunately constructing the std::hash_map with a small capacity
will lower the number of preallocated bucket slots only to 53 (-> 424
bytes under 64 bits), because this is the smallest number returned by
__stl_next_prime(). (I deduced this from the stl source in the 10.6
sdk, so I may be mistaken.)
Still a lot for the probably predominate case of a single association.
Especially if the OP is right with his observation that this memory is
scanned by the collector, which adds time overhead to the space
overhead.
Kai
On Sep 11, 2009, at 2:25 PM, Ken Ferry wrote:
Hi Torsten,
Please file as a bug if you haven't already. That clearly needs to
be
looked into.
For your KVO issue, you can probably work around it by implementing
- (void)setObservationInfo:(id)observationInfo;
- (id)observationInfo;
on the object that you are observing. This provides the storage,
and KVO
won't have to use associated references.
Note that the observation info is typed id despite being typed void
* in the
headers. KVO needs strong storage here to implement the feature
described
in "Automatic Removal of Finalized Key-Value Observers" in the
release
notes. KVO assumes you are providing strong storage if the method
is typed
id, which can be introspected out of the runtime. If you aren't,
it'll have
to use an associated reference to keep things alive.
-Ken
Cocoa Frameworks
On Fri, Sep 11, 2009 at 3:13 AM, Torsten Radtke <email@hidden
>wrote:
Is this when the first observer is added to each of the 100k
objects?
Yes, it happens for the first observer I add.
But I expressed the problem not good enough. Adding an observer is
realized
by adding an associated reference (with objc_addAssociatedObject
(), new in
Snow Leopard) to the observed object. So the main problem is that
adding a
single associative reference to an object results in an allocation
of 2048
byte block. If I do this to my 100.000 objects, about 200MB are
allocated
(in comparison to about 3MB for the objects). These blocks seem to
be
scanned memory, as I also noticed significant delays as the garbage
collector scanned and collected.
This amount of memory seems to be allocated on purpose (see
the ::reserve
method on top of the stack trace shown below) but seems way too
high for the
general case of adding a single associative reference!
0 libauto.dylib
std::vector<__gnu_cxx::_Hashtable_node<std::pair<void*
const, void*> >*,
Auto::AuxAllocator<__gnu_cxx::_Hashtable_node<std::pair<void*
const, void*>
*> >::reserve(unsigned long)
1 libauto.dylib Auto::Zone::set_associative_ref(void*, void*, void*)
2 AssociativeReferences -[Object setName:]
3 AssociativeReferences main
4 AssociativeReferences start
The Object class is implemented as follows:
static char name_key;
@implementation Object
- (NSString*)name {
return objc_getAssociatedObject(self, &name_key);
}
- (void)setName:(NSString*)aName {
objc_setAssociatedObject(self, &name_key, aName,
OBJC_ASSOCIATION_COPY);
}
@end
Torsten
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
@gmail.com
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden