Re: Garbage collection leak in simple Core Data application
Re: Garbage collection leak in simple Core Data application
- Subject: Re: Garbage collection leak in simple Core Data application
- From: Mathieu Coursolle <email@hidden>
- Date: Fri, 28 Nov 2008 15:10:30 -0500
Hi,
Thanks for your reply,
Even if I create other windows and delete them after, the lost
controllers seem to be lost forever.
I tried to select menu items and it actually speeds up the collection
of some, but some are still lost forever.
I waited for a while, continued to create/close windows, and it did
not finalize. A lot of them will finalize,
but if one is not, even if I continue to use the application for a
while, gc-roots will always show me some roots,
as it shows no roots for the finalized ones.
As a test, I added the following code in the finalize method of the
document with the same results.
for (NSWindowController* aController in [self windowControllers])
{
[self removeWindowController:aController];
NSWindow* aWindow = [aController window];
[aController setWindow:nil];
[aWindow setWindowController:nil];
}
I printed the roots again, it seems like I was able to get a bit more
info. However, it seems like there are 2 roots this time.
(gdb) info gc-roots 0x10aa2f0
Number of roots: 2
Root:
0 Kind: stack rc: 0 Address: 0xbffff2d0 Frame level: 8
Symbol: <unknown>
warning: can't find class named `NSCFArray' given by ObjC class object
1 Kind: object rc: 0 Address: 0x0121c4d0 Offset: 0x00000010
Class: NSCFArray
2 Kind: bytes rc: 0 Address: 0x01296700 Offset: 0x0000002c
3 Kind: object rc: 0 Address: 0x010a5740 Class: NSWindow
ivar: NSResponder
4 Kind: object rc: 0 Address: 0x010aa2f0 Class:
MyWindowController
Root:
0 Kind: stack rc: 0 Address: 0xbffff2f4 Frame level: 8
Symbol: <unknown>
warning: can't find class named `a' given by ObjC class object
1 Kind: object rc: 0 Address: 0x0121c4d0 Offset: 0x00000010
Class: NSCFArray
2 Kind: bytes rc: 0 Address: 0x01296700 Offset: 0x0000002c
3 Kind: object rc: 0 Address: 0x010a5740 Class: NSWindow
ivar: NSResponder
4 Kind: object rc: 0 Address: 0x010aa2f0 Class:
MyWindowController
For some strange reason, I was also unable to reproduce if my
xcdatamodel has no entity...
As a test, I modified my application to allocate memory in init, and
free it in finalize. I could clearly see in Instrument that some memory
is never freed. Finalize might not be the best place to free that
memory, but I just wanted to make sure it was not just a logging issue.
Thanks!
Mathieu
On 28-Nov-08, at 1:10 PM, Bill Bumgarner wrote:
On Nov 28, 2008, at 8:49 AM, Mathieu Coursolle wrote:
Here is the result from gc-roots for a window controller that was
not collected:
(gdb) info gc-roots 0x1048c10
Number of roots: 1
Root:
0 Kind: stack rc: 0 Address: 0xbfffee24 Frame level: 3
Symbol: <unknown>
1 Kind: object rc: 0 Address: 0x01047be0 Class: NSWindow
ivar: NSResponder
2 Kind: object rc: 0 Address: 0x01048c10 Class:
MyWindowController
(gdb) info gc-references 0x1048c10
0 Kind: object rc: 0 Address: 0x01047be0 Class: NSWindow
ivar: NSResponder
1 Kind: object rc: 0 Address: 0x01047be0 Class: NSWindow
ivar: NSResponder
2 Kind: object rc: 0 Address: 0x01047be0 Class: NSWindow
Offset: 0x0000001c
3 Kind: object rc: 0 Address: 0x01048c10 Class:
MyWindowController ivar: NSWindowController
warning: can't find class named `NSWindowAuxiliary' given by ObjC
class object
4 Kind: object rc: 0 Address: 0x01066eb0 Offset:
0x0000002c Class: NSWindowAuxiliary
warning: can't find class named `NSButtonCell' given by ObjC class
object
5 Kind: object rc: 0 Address: 0x0106f9f0 Offset:
0x00000018 Class: NSButtonCell
Should I understand that some unknown object keeps a reference to
the window, which keeps a reference to my window controller?
Unfortunately, I am not sure of how to interpret that result.
The roots are the interesting bit. The references are interesting,
too, but not for debugging this particular issue.
So -- there is a variable on the stack in frame 3 that is holding a
reference to the NSWindow, which is holding a reference to your
controller. More likely than not, this is happening because that
particular slot on the stack isn't being cleared. GCC's ABI
specifies that it *owns* the stack. That is; there is no way to
know what is where on the stack and, thus, the collector must scan
the entire stack to see if object references are lurking within.
Since the stack layout cannot be known and since the stack isn't
normally automatically zeroed, this can lead to stray references
sitting around for a while. In Leopard, the AppKit's main event
loop does automatically zero the stack from the top of the event
loop, but there can be some slots that sit *above* the zeroed area
that will hang around for a bit.
What happens if you open/close another document window? Does the
above go away? How about if you select a random menu item (info
window)? Does it go away then?
If it does, then you are running into this issue and there isn't a
huge amount that can be done. Upon tear down of the document, you
could explicitly set the window controller of the window to nil.
The window might stick around a bit longer, but the controller
won't. Yes, it can't be done in -finalize. But -finalize is
generally something to work hard to avoid having to write anyway.
b.bum
BTW: The output of roots and references looks wrong. The ivar
field seems to be spewing the wrong label....
_______________________________________________
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