[Openmcl-devel] Memory managemet Objective C and Clozure
Willem Rein Oudshoorn
woudshoo at xs4all.nl
Sat Sep 18 10:42:09 UTC 2010
Gary Byers <gb at clozure.com> writes:
> On Tue, 14 Sep 2010, Willem Rein Oudshoorn wrote:
>> I have a few questions about how the memory management of CCL and
>> Objective C work together. Hopefully it is already somewhere fully
>> documented, in that case, please point me to the right location
>> (A quick google search and reading the manual did not yield much.)
>> Let me rephrase the questions into a hypothesis and consequences.
>> If someonw can help me confirm or refute this I would appreciate it.
>> Hypothesis A:
>> 1. The objective C runtime does not know anything about
>> the lisp garbage collector
>> 2. The lisp GC and Objective-C bridge do NOT care about
>> the objective C runtime memory managment.
..[Lots of text removed]..
> It's tempting to think of ObjC objects as being close to first-class
> lisp objects. There are other ways in which this isn't true, but the
> fact that an ObjC object's lifetime isn't affected by whether or not
> there are references to it (in the GC sense) pretty much destroys the
> illusion of ... first-classness. I'd certainly prefer that things
> were were a bit lispier in that regard; making them that way likely
> does require some level of integration between the ObjC GC and the lisp
> GC, and I honestly don't know to what degree that's possible and don't
> have any real sense of how long it would take to achieve that integration if
> so. (Among other things, Apple's GC seems to be written in C++ and even
> trying to read C++ code gives me a bad headache ...)
I understand that the problem is tricky. However as things stand I get
really confused on the interaction. There seem to be some halfhearted
attempts on integrating (from reading the source.)
This subject needs some contemplation on my part, before I can even
really formulate my questions accurately. However in the mean time let
me offer the followng 'Bug'
Inconsistent Memory Management
Consider the following two class definitions:
(defclass test-objc-class-a (ns:ns-object)
(defclass test-objc-class-b (ns:ns-object)
((test-var :accessor test-var))
Now do the following:
(progn (ccl:terminate-when-unreachable (make-instance 'test-objc-class-a))
(progn (ccl:terminate-when-unreachable (make-instance 'test-objc-class-b))
(progn (make-instance 'test-objc-class-a) nil)
(let* ((instance (make-instance 'test-objc-class-b)))
It happens that:
1 - the first instance of test-objc-class-a is garbaged collected,
2 - and the instance of test-objc-class-b is NOT garbage collected.
3 - the last instance of test-objc-class-a is garbaged collected, but
4 - This leads to undefined behaviour, most likely crashing in the
It took me a while to figure this out, but
(a) There is a terminae methd on instances of ns-object
(b) This terminate message sends a #/release
(c) Per default the terminate method is not activated. Hence
results 1 and 3
(d) The fact that test-objc-class-b has lisp slots, means that the
instance is a key in the *objc-object-slot-vectors* table
and therefore will not be garbage collected. Explaining 2.
(e) the fact that the #/dealloc method is implicitly overriden,
which removes all the lisp slots from the hashtable makes
the object gc-able and therefore a new #/release message
will be send to the already 'dealloced' object.
To me it seems quite confusing. I need to think a bit more about
what I expect and if this is even a bug.
But it seems to me that the *objc-object-slot-vectors* should
be a hashtable with weak keys.
More information about the Openmcl-devel