Re: Unconventional memory leak problem
Re: Unconventional memory leak problem
- Subject: Re: Unconventional memory leak problem
- From: Rodney Kennedy <email@hidden>
- Date: Thu, 7 Sep 2006 08:10:25 +1000
I have something that appears like a memory leak with the
culprit allocations are related to drawing interface objects
such a NSTableView in 4 or so windows. This is a problem
when I run in a batch mode which induces a considerable amount of
screen drawing including rendering images. The odd thing is
when I interact with the running Application, such as click on
a window or activate or deactivate the application this induces
the AppKit deallocations. If I leave it alone as the active
application or it is not active the real and virtual memory uses
rise and the application will eventually crash.
This is not like a conventional memory leak since there are
deallocations.
I do run multiple threads but I put all drawing on the main thread.
It seems to be NSView related, induced by drawRect calls and it feels
like there needs to be periodic flushing required of something.
I now understand the problem thanks to the helpful responses I got.
Some "NSViews" when drawn induce "temporary" autoreleased objects
which at the end of the event loop are released. Trouble is the
event loop is may never run in a scenario where the user isn't
present to get the event loop to turn over. (For example I want to
run the app overnight even though I won't be awake to enjoy the
graphics.) I should point out these autorelease objects are not ones
you directly create, they occur in the AppKit or CoreGraphics
somewhere, for example, in lower level code that draws grid lines in
NSTableViews.
My interpretation, which I'm sure some people won't agree with, is
that Apple have a Tamagotchi model (for the main thread
NSAutoreleasePool). If you don't interact with some apps then they die.
So if you have an app that draws a lot (of particular types of
NSViews) then autoreleased objects can build up. The question is
should the programmer have to clean up after AppKit (or CG, or
whatever created these objects)? In the end I prefer my app to work
so I will clean it up but it strikes me that there is some flaw in
the AppKit/CG design. So there are a few ways to stop your
Tamagotchi dying:
1) Put in a "fakeEvent" that gets called every so often (an event
that say won't do anything meaningful in this case a mouseUp event in
one of my window). This worked perfectly for me. This tricks the
Tamagotchi into thinking it's being fed. This way you can guarantee
to have the main thread NSAutoreleasePool release. This is an
inelegant but simple solution.
Alternatively
2) When wanting to do drawing from a secondary thread typically you
call performSelectorOnMainThread:(SEL)aSelector
withObject:waitUntilDone: If you do so then in principle every such
aSelector needs to have its own NSAutoreleasePool, just as you would
if you had code that generated a lot of autoreleased objects (such as
in a loop with a lot of iterations) or you had a secondary thread.
This isn't elegant either. I haven't tested this solution but it will
wrap the offending allocations.
Whereas in your own code you know where and when you have creation of
autorelease objects in the case I have there are autorelease objects
which you may not know about. Generally these objects may be small,
such as 2K is size, but your memory footprint can grow in the case of
large amounts of drawing. So there is no leak; just that the main
thread autorelease pool is not guaranteed to be destroyed and
therefore autoreleased objects can build up and crash your app.
Rod
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden