Garbage collection problem

  • Hi guys,

    I've just stumbled upon a rather odd problem. I was working on a
    project that I thought had GC enabled. It turned out that, for the
    debug targets at least, GC was not enabled correctly and so the
    project was falling back on retain/release.

    This was working basically fine as the codebase had previously been
    written for retain/release. Only the new stuff doesn't have retain/
    release code.

    I enabled GC properly last evening and now there's a few errors
    cropping up. For example, in a classes init method, I get it to NSLog
    the self pointer. Then, after some time, I see errors relating to the
    class. So I attached a debugger and, sure enough, the object has
    somehow 'gone'.

    For example, from Console.app:

    09/01/2008 10:29:29 DAB Controller[6012] I am a DABSyncedController
    (<DABSyncedLoggingClient: 0x10dab30>). I am at 0x10dab30.
    ... some seconds later, from a different method ...
    09/01/2008 10:29:54 DAB Controller[6012] I am still a
    DABSyncedController (<DABSyncedLoggingClient: 0x10dab30>). I am now at
    0x10dab30.
    ... then later still, initiated by SyncServices ...
    09/01/2008 10:29:55 DAB Controller[6012] *** -[NSCFArray
    client:mightWantToSyncEntityNames:]: unrecognized selector sent to
    instance 0x10dab30
    09/01/2008 10:29:55 DAB Controller[6012] ISyncManager: exception
    raised during sync alert callout. A session will not be created: *** -
    [NSCFArray client:mightWantToSyncEntityNames:]: unrecognized selector
    sent to instance 0x10dab30

    After attaching the debugger:

    (gdb) po (id)(0x10dab30)

    Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: KERN_INVALID_ADDRESS at address: 0xfef252df
    ...
    (gdb) p (id)(0x10dab30)
    $1 = (id) 0x10dab30
    (gdb) p *(id)(0x10dab30)
    $2 = {
      isa = 0xfef252bf
    }

    That indicates to me the object has been garbage collected.

    My query is, first, how can this be?! But second, is there anything I
    can or should be doing to influence the GC? Or even if I could just
    debug GC events it might help me understand why the GC is collecting
    my object.

    Any pointers gratefully received!

    Thanks,
    denty.

    --
    http://www.QQdd.eu/
  • Hi,

    On 2008-01-09, at 21:15, Dent John wrote:

    > For example, in a classes init method, I get it to NSLog the self
    > pointer. Then, after some time, I see errors relating to the class.

    Are you storing a reference to that instance in a "strong" location,
    such as a global variable? Otherwise the garbage collector has no idea
    that it might be used later on.

    Jonathon Mah
    <me...>
  • Hi Jonathon,

    So, thanks for the quick response there.

    The object in question is instantiated in my NIB and, though is not
    visible, it has outlets to other objects (specifically an array
    controller and a spinning circle thing). I figured that would be
    strong enough to prevent collection.

    Also, the self is obviously stored in SyncServices as it knows that
    it's a callback-able class for when of tries to
    client:mightWantToSyncEntityNames:.

    I implemented the finalize method just now and, sure enough, the
    object is getting collected.

    I'll try making the object pop itself into a global to see if it helps.

    d.
    --
    Sent from my iPhone

    On 9 Jan 2008, at 11:57, Jonathon Mah <me...> wrote:

    > Hi,
    >
    > On 2008-01-09, at 21:15, Dent John wrote:
    >
    >> For example, in a classes init method, I get it to NSLog the self
    >> pointer. Then, after some time, I see errors relating to the class.
    >
    >
    > Are you storing a reference to that instance in a "strong" location,
    > such as a global variable? Otherwise the garbage collector has no
    > idea that it might be used later on.
    >
    >
    >
    > Jonathon Mah
    > <me...>
  • Clark Cox III
    <Clark.cox...>
    Sent from my iPhone

    On Jan 9, 2008, at 5:24, Dent John <denty...> wrote:

    > Hi Jonathon,
    >
    > So, thanks for the quick response there.
    >
    > The object in question is instantiated in my NIB and, though is not
    > visible, it has outlets to other objects (specifically an array
    > controller and a spinning circle thing). I figured that would be
    > strong enough to prevent collection.

    That is not enough. The object needs pointers pointing *to* it in
    order to be kept around.

    >
    >
    > Also, the self is obviously stored in SyncServices as it knows that
    > it's a callback-able class for when of tries to
    > client:mightWantToSyncEntityNames:.

    If the syncservices docs claim to retain the object, then I'd file a
    bug. Otherwise, you cannot assume that it will keep your object around.

    >
    >
    > I implemented the finalize method just now and, sure enough, the
    > object is getting collected.
    >
    > I'll try making the object pop itself into a global to see if it
    > helps.
    >
    > d.
    > --
    > Sent from my iPhone
    >
    > On 9 Jan 2008, at 11:57, Jonathon Mah <me...> wrote:
    >
    >> Hi,
    >>
    >> On 2008-01-09, at 21:15, Dent John wrote:
    >>
    >>> For example, in a classes init method, I get it to NSLog the self
    >>> pointer. Then, after some time, I see errors relating to the class.
    >>
    >>
    >> Are you storing a reference to that instance in a "strong"
    >> location, such as a global variable? Otherwise the garbage
    >> collector has no idea that it might be used later on.
    >>
    >>
    >>
    >> Jonathon Mah
    >> <me...>

  • Its not the pointers you need to recieve. Its the objects!

    Sorry, couldn't resist te pun. I'm a noob but I heard about this when
    Xcode's build settings aren't set properly.

    They're heirarchical I think so you can set collection on in the
    project roots 'get info' but it can then be overrided by the target's
    'get info' build settings.

    Not sure if its still the case with Xcode 3.0 but might be worth
    setting GC on by selecting 'get info' on the target.

    Correct me if I'm wrong with this whole thing.

    Jonathan Dann
  • On Jan 9, 2008, at 5:24 AM, Dent John wrote:

    > The object in question is instantiated in my NIB and, though is not
    > visible, it has outlets to other objects (specifically an array
    > controller and a spinning circle thing). I figured that would be
    > strong enough to prevent collection.
    >
    <http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection
    /Articles/gcEssentials.html#//apple_ref/doc/uid/TP40002452-SW7
    >

    mmalc
  • Hi Jonathan,

    On Jan 9, 2008, at 14:40, Jonathan Dann wrote:

    > Its not the pointers you need to recieve. Its the objects!
    >
    > Sorry, couldn't resist te pun. I'm a noob but I heard about this
    > when Xcode's build settings aren't set properly.

    Yes – I guess I have to admit to falling victim to the RFTM properly
    suggestion. Which I admit that I hadn't done recently. Even so, I do
    think that making NIB objects collectable is quite funny. After all,
    they are there in the NIB for a good reason!! Still, it is not ours to
    reason why. :-)

    > They're heirarchical I think so you can set collection on in the
    > project roots 'get info' but it can then be overrided by the
    > target's 'get info' build settings.
    >
    > Not sure if its still the case with Xcode 3.0 but might be worth
    > setting GC on by selecting 'get info' on the target.
    >
    > Correct me if I'm wrong with this whole thing.

    No – you're not wrong. That's exactly what I found the issue to be.
    But thanks for taking the time to suggest it.

    > Jonathan Dann

    --
    http://www.QQdd.eu/
  • On Jan 10, 2008, at 1:27 AM, Dent John wrote:
    >> Sorry, couldn't resist te pun. I'm a noob but I heard about this
    >> when Xcode's build settings aren't set properly.
    >
    > Yes – I guess I have to admit to falling victim to the RFTM properly
    > suggestion. Which I admit that I hadn't done recently. Even so, I do
    > think that making NIB objects collectable is quite funny. After all,
    > they are there in the NIB for a good reason!! Still, it is not ours
    > to reason why. :-)

    It would have required new API to support some kind of top level
    collection returned by the NIB that, ultimately, would have been a
    waste of memory.

    The easiest solution for non-mainmenu NIBs is to create outlets on
    your File's Owner for each of the top level objects (of which there
    are typically few).

    For the mainmenu nib, create said outlets on the app delegate instance
    (make sure File's Owner's delegate outlet is connected to your
    delegate instance.

    b.bum
  • On Jan 10, 2008 8:58 AM, Bill Bumgarner <bbum...> wrote:
    > On Jan 10, 2008, at 1:27 AM, Dent John wrote:
    >>> Sorry, couldn't resist te pun. I'm a noob but I heard about this
    >>> when Xcode's build settings aren't set properly.
    >>
    >> Yes – I guess I have to admit to falling victim to the RFTM properly
    >> suggestion. Which I admit that I hadn't done recently. Even so, I do
    >> think that making NIB objects collectable is quite funny. After all,
    >> they are there in the NIB for a good reason!! Still, it is not ours
    >> to reason why. :-)
    >
    > It would have required new API to support some kind of top level
    > collection returned by the NIB that, ultimately, would have been a
    > waste of memory.
    >
    > The easiest solution for non-mainmenu NIBs is to create outlets on
    > your File's Owner for each of the top level objects (of which there
    > are typically few).

    Or to load the nib via NSNib, which has the method:

    - (BOOL)instantiateNibWithOwner:(id)owner topLevelObjects:(NSArray
    **)topLevelObjects;

    for just this reason. Pass in a pointer to a variable as the second
    parameter, and it will be set to an NSArray containing all such
    top-level objects.

    --
    Clark S. Cox III
    <clarkcox3...>
  • Filed as bug # 5685715 as the API docs don't say either way.

    The equivalent (but process-oriented) method, setSyncAlertToolPath:,
    does claim to retain it's arguments, so I think clarification in the
    documentation would be good.

    The workaround of referencing the object from a dummy outlet in the
    delegate worked.

    Thanks,
    denty.

    On Jan 9, 2008, at 13:54, Clark S. Cox III wrote:

    >
    >
    > Clark Cox III
    > <Clark.cox...>
    > Sent from my iPhone
    >
    > On Jan 9, 2008, at 5:24, Dent John <denty...> wrote:
    >
    >> Hi Jonathon,
    >>
    >> So, thanks for the quick response there.
    >>
    >> The object in question is instantiated in my NIB and, though is not
    >> visible, it has outlets to other objects (specifically an array
    >> controller and a spinning circle thing). I figured that would be
    >> strong enough to prevent collection.
    >
    > That is not enough. The object needs pointers pointing *to* it in
    > order to be kept around.
    >
    >>
    >>
    >> Also, the self is obviously stored in SyncServices as it knows that
    >> it's a callback-able class for when of tries to
    >> client:mightWantToSyncEntityNames:.
    >
    > If the syncservices docs claim to retain the object, then I'd file a
    > bug. Otherwise, you cannot assume that it will keep your object
    > around.
    >
    >>
    >>
    >> I implemented the finalize method just now and, sure enough, the
    >> object is getting collected.
    >>
    >> I'll try making the object pop itself into a global to see if it
    >> helps.
    >>
    >> d.
    >> --
    >> Sent from my iPhone
    >>
    >> On 9 Jan 2008, at 11:57, Jonathon Mah <me...> wrote:
    >>
    >>> Hi,
    >>>
    >>> On 2008-01-09, at 21:15, Dent John wrote:
    >>>
    >>>> For example, in a classes init method, I get it to NSLog the self
    >>>> pointer. Then, after some time, I see errors relating to the class.
    >>>
    >>>
    >>> Are you storing a reference to that instance in a "strong"
    >>> location, such as a global variable? Otherwise the garbage
    >>> collector has no idea that it might be used later on.
    >>>
    >>>
    >>>
    >>> Jonathon Mah
    >>> <me...>


    --
    http://www.QQdd.eu/
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today