[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
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