[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