[Openmcl-devel] Memory managemet Objective C and Clozure
Willem Rein Oudshoorn
woudshoo at xs4all.nl
Tue Sep 21 18:36:26 UTC 2010
Thank you, this explains a lot. I didn't realize that not all lisp
references to an Objective-C instance are the same.
Gary Byers <gb at clozure.com> writes:
> On Sun, 19 Sep 2010, Willem Rein Oudshoorn wrote:
>> Strange behaviour in memory magement
>> I am still convinced the following is not right:
>> 1 - If you create an instance of an subclass of ns:ns-object
>> with lisp slots
>> 2 - You should never use (ccl:terminate-when-unreachable)
>> on that instance because:
>> 3 - the *objc-object-slot-vectors* keeps a reference to the instance
> You're right. Neither the pointer used as a key in
> *OBJC-OBJECT-SLOT-VECTORS* nor the slot-vector's backpointer to the
> instance should be EQ to any existing lisp pointer to the instance.
Now I understand it better, I agree with the should. However,
unfortunately, as far as I can tell it isn't. Or I should say
it wasn't. I just see that you fixed that behaviour, thank you.
>> 6 - Terminate calls #/release [which is wrong!]
>> (This could potentially
>> be solved by canceling the 'terminate' call in the dealloc call.
>> However I assume that this prevents user code for using the
>> terminate. Which could be considered bad as well.)
> Having the TERMINATE method call #/release is correct and useful.
Sorry, for the confusion, I meant that calling #/release on an object
which was deallocated in stel 4 is wrong. Not that the idea to call
#/release in terminate was wrong. (I tend to think about this from
the Objective-C side.)
Anyway, with your fix, things make a whole lot more sense.
>> What would I expect
>> I have thought a little about it, but what I would expect is that:
>> 1 - As soon as a lisp reference to an objective-C object 'o' is created
>> 'o' is send a #/retain message. [*]
>> 2 - As soon as the garbage collector discovers that reference
>> is not longer accessible from the lisp side,
>> it sends a #/release message
>> 3 - If the #/dealloc is called, everything is cleaned up.
[Enlightening example from Gary Bayers removed]
[Gary Bayers explains that such a scheme is prohibitive expensive:
> ... If the method is called
> thousands of times between GCs, then the view will get retained
> thousands of times and thousands of lisp pointers to thousands of
> (otherwise short-lived) NSEvents will be retained (interfering with
> things like #/autorelease). I don't think that I'd want to ever move
> the mouse if that meant going through a largely pointless cycle of
> registering for termination, #/retain, GC, TERMINATE, #/release.
I don't have experience with this scheme and I immediately take
your word for it. It is a bit of a shame, it would in my eyes make
the bridge just a bit simpler to use.
> ..... - but the real problem was that it
> makes much more sense to retain a canonicalized pointer to an NSView
> than it does to retain a canonicalized pointer to an autoreleased NSEvent,
> and I saw no way of automating the process of distinguishing between those
I don't want to drag this on, so just ignore this if you have more fun
things to do than answering this.
But with the above point I don't agree, I would not want to make a
distinction between the 'autoreleased' event and the 'nsview'.
If such a scheme is implemented, it should be uniform, for all objects
the same, otherwise I think will create more headaches than it solves.
Also I assume that the cost is mainly on the lisp side. Just sending
a pair of #/retain #/release is worth it, IMO. But if indeed the cost
is much higher, it might not be good.
> ... If some (alleged) lisp references to ObjC objects were
> guaranteed safe and others weren't (and it was hard to know/remember
> which were which), that's not different enough from the status quo
> to accept some pervasive overhead.
I am in full agreement here.
Thank you again for explaining it all to me (and fixing the
More information about the Openmcl-devel