Re: GC app not releasing memory until click, even if I send
Re: GC app not releasing memory until click, even if I send
- Subject: Re: GC app not releasing memory until click, even if I send
- From: "Mark Aufflick" <email@hidden>
- Date: Sat, 25 Oct 2008 16:18:55 +1100
Of course. I was trying to get the default autorelease pool to drain
it, but I just need to operate on the defaultCollerctor.
Your last piece of advice alomst worked - I had to:
[[NSGarbageCollector defaultCollector] collectExhaustively];
I'm not doing anything fancy with the runloop - just the Xcode cocoa
application template. I set up the observer via
[NSDistributedNotificationCenter defaultCenter] addObserver:... in
awakeFromNib of a controller. No explicit threads.
Do you think that constitutes a radar? It certainly seems like the
collector should run since events are being received in the run loop
(evidenced by an NSLog in sendEvent).
Thanks so much for your help - I would have beaten release pools to
death before I looked at NSGarbageCollector...
Mark.
On Sat, Oct 25, 2008 at 3:21 PM, Bill Bumgarner <email@hidden> wrote:
> On Oct 24, 2008, at 8:52 PM, Mark Aufflick wrote:
>>
>> I'm going mental here. I have an app, using garbage collection, that
>> responds to distributed notifications. All the memory allocated by the
>> method that responds to those notifications builds up (watching in top
>> or Instruments) until a real UI event is recieved - click on a
>> menu/window etc.
>
> Yeah... that ain't right. But I'll need to know more about your app....
>
> See below.
>
>> To try to flog the event loop into draining the pool I post an
>> NSApplicationDefined event as per
>> http://www.mikeash.com/?page=pyblog/more-fun-with-autorelease.html and
>> other documents, but it doesn't clear the memory. I know the event is
>> being posted because if I subclass NSApplication I can log the events
>> being recieved in sendEvent:
>>
>> [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined
>> location:NSZeroPoint
>> modifierFlags:0
>> timestamp:0
>> windowNumber:0
>> context:nil
>> subtype:0
>> data1:0
>> data2:0]
>> atStart:YES];
>>
>> Is there something special I need to do to have the garbaage
>> collection collect inside a notification observer? If I let the
>> application run overnight being fed regular notifications, the size
>> gets over 100Mb of wasted memory, which I assume would be beyond the
>> garbage collection threshold? Certainly any click on the app drops it
>> down to 14Mb immediately.
>
> OK.... "being fed regular notifications". Are the notifications being
> handled on the main thread? Are you running a runloop (I would imagine you
> would have to be to have the above work) in a standard fashion?
>
> Any threads?
>
> Have you used the various tools on the system -- Object Graph in
> Instruments, malloc stack logging, malloc history, etc... -- to see what
> objects are hanging about?
>
> ---
>
> On to possible reasons why.
>
> Given the lack of information, this is conjecture at the moment.
>
> (1) The further you move away from NSRunLoop, the more likely that you are
> running into artificial rooting caused by the stack. That is, the stack
> must be scanned conservatively because the compiler does not offer any way
> to know exactly where every object reference on the stack might reside.
> Thus, NSRunLoop will periodically clear the stack -- zero out the stack --
> to eliminate any phantom references. It may be that you have created a
> situation where this clearing is not happening or is incomplete.
>
> You can use objc_clear_stack() -- see /usr/include/objc/objc-auto.h -- to
> clear the stack.
>
> See:
>
> http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcAPI.html#//apple_ref/doc/uid/TP40002467-SW14
>
> (2) However, given that the memory is building up over time, this indicates
> that something else is going on. That the memory is reaped when you trigger
> a UI event indicates that there is a collection class or something somewhere
> that is gathering together the memory over time. This seems unlikely, but
> possible.
>
> To figure this one out, you'll really need to figure out what is hanging
> around that shouldn't.
>
> If you do, please share. If you don't want to share ;), file a radar and
> send me the bug number -- at the very least, documenting the pitfall is
> warranted.
>
> (3) I saved the simplest potential explanation for last.
>
> It might be that your program is just different enough from the well tested
> patterns that it fell through a collection crack. In particular, the
> collector interacts with the AppKit to such that the collector is
> effectively hinted as to when good times to collect might be. This hinting
> is pretty critical to the collector (for now -- the goal, of course, is to
> eliminate the need for any hinting while maximizing performance).
>
> If you were to call [[NSGarbageCollector defaultCollector] collectIfNeeded];
> at the end of processing notifications, that very likely might fix the
> issue.
>
> If this is the case, filing a bug is warranted. If it is the case that a
> pure distributed notifications only application does not reap garbage, I
> want to know.
>
> b.bum
>
>
--
Mark Aufflick
contact info at http://mark.aufflick.com/about/contact
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden