[Openmcl-devel] Memory managemet Objective C and Clozure
Willem Rein Oudshoorn
woudshoo at xs4all.nl
Sun Sep 19 01:48:32 PDT 2010
Gary,
Thank you for taking your time to answer, but
I get the feeling we are not understanding each other clearly.
So let me give some background on my experience,
1 - I have programmed extensively in Objective-C and the Foundation
Framework on OpenStep (not the AppKit framework however). For this
I have done overwriting dealloc, writing new proxy classes, changing
classtypes on the fly for debugging purposes and hacked up the
GNUstep runtime to debug memory management.
So I think I got a decent grasp at the Apple Foundation
#release/#retain/#autorelease mechanism.
[This is not to say that I am expert or do not mess up
occassionally, but more to point out where I am coming from.]
2 - I am relatively new to lisp, and completely new to the
Clozure Objective-C bridge
3 - My main problem is trying to get my head around mixing
garbage collection with the Objective-C memory management.
4 - My previous e-mail was more to explain what I found confusing,
I did understand that some examples could never work.
The idea was more to show how subtle of a difference there
was between working and non-working code, and that it
depends if you have lisp slots or not.
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
4 - This reference only goes away when the #/dealloc is called
5 - So terminate will only be called AFTER dealloc.
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.)
I naively made the remark that I thought *objc-object-slot-vectors*
should have weak keys, but as you pointed out that does not work.
Gary Byers <gb at clozure.com> writes:
[About the *objc-object-slot-vectors* hash-table]
> A weak hash table could tell us when an encapsulating lisp object
> becomes garbage, but that isn't what we want to know in this and
> similar cases: the slot-vector should exist as long as the ObjC
> object exists. (If all encapsulating lisp pointers to the ObjC
> object became garbage, we can't safely remove the slot-vector because
> some might create a new encapsulating pointer to the object or receive
> such a pointer as an argument)
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.
However I can see that step 2 conflicts with the
*objc-object-slot-vectors* hashtable. Because the garbage collector
will always see a reference to the object from the hashtable.
[*] For me this means that (setf *i* (make-instance 'ns:ns-object)) would have
retainCount 2, 1 for the alloc/init, and 1 for the lisp side
reference to it. This would be at least consistent
with the objective C behavior that i = [[NSObject alloc] init] leaks
as long as you do not send a release message.
But you could also easily argue that it should be 1, to be more like
lisp objects.
I hope this made things clearer.
Wim Oudshoorn
More information about the Openmcl-devel
mailing list