[Openmcl-devel] Fix memory leak in an objc example

R. Matthew Emerson rme at clozure.com
Wed Apr 30 18:48:17 PDT 2014


On Apr 30, 2014, at 9:04 PM, Leo Liu <sdl.web at gmail.com> wrote:

> On 2014-04-30 17:32 -0500, Paul Krueger wrote:
>> It may be that what you think is a memory leak is just a consequence
>> of Lisp garbage collection not running between loop iterations. If you
>> want to test that, put an explicit call (gc) inside that loop and see
>> if the "leak" goes away.
> 
> With (ccl:gc) inserted between calls, the increase is 2M.
> 
>> What does (all-applications) do? If you're doing some objective-C
>> stuff there then unless you are explicitly calling #/release on
>> everything you #/alloc, then that might be causing a problem as well.
> 
> all-applications calls a c function `_LSCopyAllApplicationURLs' which
> returns a mutable nsarray of NSURLs. all-applications converts that
> nsarray to a list of strings for lisp.
> 
> I tried putting a #/autorelease on (ccl:%get-ptr urls) and the memory
> leak seems to be gone. Does this mean we always have to release rlet's
> pointers?

You're confusing unrelated things.

What rlet does is to allocate some memory on the stack.

According to Apple's conventions, because _LSCopyAllApplicationURLs
has the word "copy" in it, you "own" whatever it returns, and must
release it when you're done with it.

So, you might say
(let ((array (%get-ptr urls)))
  ;; use array
  (#/release array) ;or (#_CFRelease array)

The main difference between #/release and #_CFRelease is that the
call to #_CFRelease will crash if you pass it a null pointer (as
made by (ccl:%null-ptr) or +null-ptr+), and #/release won't.  As with
all Objective-C methods, sending a message to a null pointer returns
a null pointer.

>> Many Objective-C apps use automatic garbage collection rather than
>> explicit memory management using release calls, but you cannot do that
>> inside CCL.

ARC (automatic reference counting) is what Apple is currently recommending
for most Objective-C applications.  It isn't a GC.  (They had a GC, but it's
deprecated.) I believe ARC works largely by static analysis: the compiler
decides, at compile-time, where to insert retain and release methods.

>> Lisp does not do any automatic garbage collection for
>> Objective-C objects; it relies on the objective-c runtime code to do
>> that when appropriate #/release calls are made (or #/autorelease if
>> you take care to set up an autorelease pool to make that work). There
>> are other memory management issues to understand if you create Lisp
>> classes that inherit from Objective-C classes, but I presume that you
>> aren't doing that.





More information about the Openmcl-devel mailing list