[Openmcl-devel] Memory managemet Objective C and Clozure

Willem Rein Oudshoorn woudshoo at xs4all.nl
Sat Sep 18 03:42:09 PDT 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)
  (:metaclass ns:+ns-object))

(defclass test-objc-class-b (ns:ns-object)
  ((test-var :accessor test-var))
  (:metaclass ns:+ns-object))

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)))
      (ccl:terminate-when-unreachable instance)
      (#/release instance)

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
     leaks memory.
4 -  This leads to undefined behaviour, most likely crashing in the
     objective-C runtime.

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.   

Kind regards,
Wim Oudshoorn.


More information about the Openmcl-devel mailing list