Re: Lost memory, GCD, dispatch sources, Cocoa bindings & User interface
Re: Lost memory, GCD, dispatch sources, Cocoa bindings & User interface
- Subject: Re: Lost memory, GCD, dispatch sources, Cocoa bindings & User interface
- From: Jean Suisse <email@hidden>
- Date: Wed, 16 Sep 2015 21:37:41 +0200
Hi Jonny,
I also have a feeling the issue lies somewhere between the dispatch mechanism and Core Animation. I have seen some funny things too. For instance, I can’t run a serial queue for months. Some objects escape the autorelease pool created in the block (and seemingly encompassing everything in it) and are only released when the queue is empty. Looks like for some reason GCD waits for the queue to be idle to release certain objects (which are probably not mine).
Workarounds : I don’t post all blocks on the queue. Just enough to run for a few hours. The last blocks on the queue triggers the next few blocks to be posted on a second queue and so on...
OR the last block on the queue posts a block on the main thread, which kills the queue after the posting block has exited. Re-creates the queue and posts the next blocks.
What catches my attention in you message is: memory drops significantly when you click the mouse or switch applications.
I have observed this behavior. One of my app, which runs for months, eventually crashes and suffers the same issue as described here. I have observed that:
– When switching apps with CMD-TAB, I can have huge drops in consumed memory (hundreds of MB). Sometimes, hitting CMD-TAB causes the app not to continue eating memory. Sometimes, it causes the app to start eating memory again. BUT, when the “right” CMD–TAB that prevents the app from eating memory occurs, it is not a permanent fix. The app will resume eating memory by itself when left alone.
– The amount of memory eaten is not related to the rate at which my app runs its measurements cycles (so my code does not leak), but only when this rate is too fast for UI update to keep up (thus pointing towards UI update-related problem).
– The app doesn’t have memory issues if I run it without actually unpacking the NIB containing the view that displays the results (the view is just an instance of NSView holding labels with number formatters, mostly).
Unfortunately, what makes the app so hard to debug in Instruments, is that by running, it creates and destroys billions of objects quickly (I do data processing, store data points in text files, perform operations on strings, etc.). Instruments just can’t cope with it, slows down quickly, takes GB of memory space… etc.
What I can tell so far is that
1. the memory is not being leaked (no leaks reported by instruments) but 97.0 % of the memory (heap marks 6 seconds appart) occupied is taken after:
Bytes Used Count Symbol Name
690.19 KB 98.1% 9478 __CFRunLoopDoObservers
…….
Bytes Used Count Symbol Name
682.42 KB 97.0% 9319 CA::Layer::display_()
More Specifically:
Bytes Used Count Symbol Name
679.89 KB 96.6% 9265 -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inGraphicsContext:CGContext:topView:shouldChangeFontReferenceColor:]
349.53 KB 49.6% 5164 -[NSControl drawRect:]
203.28 KB 28.9% 3035 -[NSView(NSInternal) _setupFontSmoothingForLayerDrawingIntoContext:previousColor:previousFlag:]
126.80 KB 18.0% 1060 -[NSMatrix drawRect:]
2. I did show all the incriminated code in my first post.
And I can’t think how self.myProperty = self->myInstanceVariable can leak under ARC.
3. Running without UI shows no issue.
4. The UI is only a bunch of NSTextFields with bindings.
I will try to “tickle” the main loop into draining autoreleased objects and report back.
Thanks,
Jean
> On 16 sept. 2015, at 20:29, Jonathan Taylor <email@hidden> wrote:
>
> Hi Jean,
>
> A wild guess that might or might not have any relevance to your problem: I see that you are wrapping your blocks with an autorelease pool, and that reminded me of a problem I dealt with a while back.
>
> As I understand it (and as discussed on this list some while back I think) pools may not always be drained when you expect. I'm not sure if that applies to explicitly generated ones, but it certainly seems to apply to little snippets of callback code (e.g. UI accessors) that may be called from within the main event loop. I have a dim recollection there may be some funny stuff with GCD-related code as well.
>
> Anyway, I have the following little bit of code in my application. I don't remember all the details now, so the comment itself (and perhaps a trawl through the list archives for that text) will have to serve as an explanation:
>
> // Create a periodic timer that "tickles" the main event loop to drain autorelease pools.
> // Response from cocoa-dev discussion was that:
> // This is a long-standing problem with AppKit. According to the documentation,
> // "The Application Kit creates an autorelease pool on the main thread at the
> // beginning of every cycle of the event loop, and drains it at the end, thereby
> // releasing any autoreleased objects generated while processing an event."
> // However, this is somewhat misleading. The "end" of the event loop cycle is
> // immediately before the beginning. Thus, for example, if your app is in the background
> // and not receiving events, then the autorelease pool will not be drained. That's why
> // your memory drops significantly when you click the mouse or switch applications.
> [JDispatchTimer allocRepeatingTimerOnQueue:dispatch_get_main_queue() atInterval:5.0 withHandler:^{
> NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:[NSDate timeIntervalSinceReferenceDate] windowNumber:0 context:nil subtype:0 data1:0 data2:0];
> [NSApp postEvent:event atStart:YES];
> }];
>
>
> I wonder if that would be any help with your case - either for the exact reasons I encountered, or for some reason along similar lines. It just might be a wild stab in the dark at a quick (but obscure) fix, but if it doesn't help then I guess you'll have to start exploring things with Instruments as others have suggested.
>
> Cheers
> Jonny
_______________________________________________
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