gc.garbage

Discussion in 'Python' started by 7stud, Aug 30, 2007.

  1. 7stud

    7stud Guest

    gc.garbage returns an empty list even though the command:

    gc.set_debug(gc.DEBUG_LEAK)

    produces the following output:

    gc: uncollectable <Dog 0x56e10>
    gc: uncollectable <Cat 0x56e30>
    gc: uncollectable <dict 0x58270>
    gc: uncollectable <dict 0x43e40>

    I expected all those objects to be in the list returned by
    gc.garbage. Here's the code:

    import gc

    class Cat(object):
    def __del__():
    pass

    class Dog(object):
    def __del__():
    pass

    def some_func():
    the_dog = Dog()
    the_cat = Cat()
    the_dog.cat = the_cat
    the_cat.dog = the_dog

    some_func()

    gc.set_debug(gc.DEBUG_LEAK)
    print gc.garbage

    --output:--
    []
    gc: uncollectable <Dog 0x56e10>
    gc: uncollectable <Cat 0x56e30>
    gc: uncollectable <dict 0x58270>
    gc: uncollectable <dict 0x43e40>
    7stud, Aug 30, 2007
    #1
    1. Advertising

  2. > gc.set_debug(gc.DEBUG_LEAK)
    > print gc.garbage
    >
    > --output:--
    > []
    > gc: uncollectable <Dog 0x56e10>
    > gc: uncollectable <Cat 0x56e30>
    > gc: uncollectable <dict 0x58270>
    > gc: uncollectable <dict 0x43e40>


    gc.garbage is filled only after these messages
    are printed, not before. You need to add an explicit
    call to gc.collect() if you want to see what
    uncollectable garbage you have.

    Regards,
    Martin
    =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=, Aug 30, 2007
    #2
    1. Advertising

  3. 7stud

    7stud Guest

    On Aug 30, 3:50 am, "Martin v. Löwis" <> wrote:
    > > gc.set_debug(gc.DEBUG_LEAK)
    > > print gc.garbage

    >
    > > --output:--
    > > []
    > > gc: uncollectable <Dog 0x56e10>
    > > gc: uncollectable <Cat 0x56e30>
    > > gc: uncollectable <dict 0x58270>
    > > gc: uncollectable <dict 0x43e40>

    >
    > gc.garbage is filled only after these messages
    > are printed, not before. You need to add an explicit
    > call to gc.collect() if you want to see what
    > uncollectable garbage you have.
    >
    > Regards,
    > Martin


    Hi,

    Thanks for the response. Now, when I run the code:

    ------------
    import gc

    class Cat(object):
    pass

    class Dog(object):
    pass

    def some_func():
    the_dog = Dog()
    the_cat = Cat()
    the_dog.cat = the_cat
    the_cat.dog = the_dog

    some_func()

    gc.set_debug(gc.DEBUG_LEAK)
    gc.collect()
    print gc.garbage
    ----------------

    I get this output:

    -------------
    gc: uncollectable <Dog 0x56e10>
    gc: uncollectable <Cat 0x56e30>
    gc: uncollectable <dict 0x58300>
    gc: uncollectable <dict 0x43e40>
    [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    object at 0x56e10>}]
    ---------------

    Why are there two entries in the list for each uncollectable object?
    Also, I haven't bound the names "cat" or "dog" anywhere in my
    program. What do those names mean in the list?

    Doing some more testing, if I remove the __del__ methods:

    ---------------
    class Cat(object):
    pass

    class Dog(object):
    pass

    def some_func():
    the_dog = Dog()
    the_cat = Cat()
    the_dog.cat = the_cat
    the_cat.dog = the_dog

    some_func()

    gc.set_debug(gc.DEBUG_LEAK)
    gc.collect()
    print gc.garbage
    -----------

    I get this output:

    -----------------
    gc: collectable <Dog 0x56e10>
    gc: collectable <Cat 0x56e30>
    gc: collectable <dict 0x58270>
    gc: collectable <dict 0x43e40>
    [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    object at 0x56e10>}]
    ----------------

    Now the objects are marked as collectable. The docs say:

    ----
    garbage
    A list of objects which the collector found to be unreachable but
    could not be freed (uncollectable objects).
    ----

    So, I expected gc.garbage to be empty. The docs also say:

    ----
    garbage
    ....By default, this list contains only objects with __del__() methods.
    ----
    7stud, Aug 30, 2007
    #3
  4. 7stud

    7stud Guest

    On Aug 30, 3:50 am, "Martin v. Löwis" <> wrote:
    > > gc.set_debug(gc.DEBUG_LEAK)
    > > print gc.garbage

    >
    > > --output:--
    > > []
    > > gc: uncollectable <Dog 0x56e10>
    > > gc: uncollectable <Cat 0x56e30>
    > > gc: uncollectable <dict 0x58270>
    > > gc: uncollectable <dict 0x43e40>

    >
    > gc.garbage is filled only after these messages
    > are printed, not before. You need to add an explicit
    > call to gc.collect() if you want to see what
    > uncollectable garbage you have.
    >
    > Regards,
    > Martin


    Hi,

    Thanks for the response. I had a cut and paste error in my reply, so
    here it is again with the corrections...

    Now, if I run the code:

    ------------
    import gc

    class Cat(object):
    def __del__():
    pass

    class Dog(object):
    def __del__():
    pass

    def some_func():
    the_dog = Dog()
    the_cat = Cat()
    the_dog.cat = the_cat
    the_cat.dog = the_dog

    some_func()

    gc.set_debug(gc.DEBUG_LEAK)
    gc.collect()
    print gc.garbage
    -----------

    I get this output:

    ----------
    gc: uncollectable <Dog 0x56e10>
    gc: uncollectable <Cat 0x56e30>
    gc: uncollectable <dict 0x58300>
    gc: uncollectable <dict 0x43e40>
    [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    object at 0x56e10>}]
    -----------

    Why are there two entries in the list for each uncollectable
    object(same addresses)? Also, I haven't bound the names "cat" or
    "dog" anywhere in my program. What do those names mean in the list?

    Doing some further testing, if I eliminate the __del__ methods:

    -----------
    import gc

    class Cat(object):
    pass

    class Dog(object):
    pass

    def some_func():
    the_dog = Dog()
    the_cat = Cat()
    the_dog.cat = the_cat
    the_cat.dog = the_dog

    some_func()

    gc.set_debug(gc.DEBUG_LEAK)
    gc.collect()
    print gc.garbage
    -------------------

    I get this output:

    -----
    gc: collectable <Dog 0x56e10>
    gc: collectable <Cat 0x56e30>
    gc: collectable <dict 0x58270>
    gc: collectable <dict 0x43e40>
    [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    object at 0x56e10>}]
    -----

    The docs say:

    ---------
    garbage
    A list of objects which the collector found to be unreachable but
    could not be freed (uncollectable objects).
    --------

    Since debugging doesn't show any uncollectable objects, why isn't
    gc.garbage empty? The docs also say:

    ----
    garbage
    ....By default, this list contains only objects with __del__() methods.
    ----

    Does set_debug() change the default?
    7stud, Aug 30, 2007
    #4
  5. 7stud

    Chris Mellon Guest

    On 8/30/07, 7stud <> wrote:
    > On Aug 30, 3:50 am, "Martin v. Löwis" <> wrote:
    > > > gc.set_debug(gc.DEBUG_LEAK)
    > > > print gc.garbage

    > >
    > > > --output:--
    > > > []
    > > > gc: uncollectable <Dog 0x56e10>
    > > > gc: uncollectable <Cat 0x56e30>
    > > > gc: uncollectable <dict 0x58270>
    > > > gc: uncollectable <dict 0x43e40>

    > >
    > > gc.garbage is filled only after these messages
    > > are printed, not before. You need to add an explicit
    > > call to gc.collect() if you want to see what
    > > uncollectable garbage you have.
    > >
    > > Regards,
    > > Martin

    >
    > Hi,
    >
    > Thanks for the response. I had a cut and paste error in my reply, so
    > here it is again with the corrections...
    >
    > Now, if I run the code:
    >
    > ------------
    > import gc
    >
    > class Cat(object):
    > def __del__():
    > pass
    >
    > class Dog(object):
    > def __del__():
    > pass
    >
    > def some_func():
    > the_dog = Dog()
    > the_cat = Cat()
    > the_dog.cat = the_cat
    > the_cat.dog = the_dog
    >
    > some_func()
    >
    > gc.set_debug(gc.DEBUG_LEAK)
    > gc.collect()
    > print gc.garbage
    > -----------
    >
    > I get this output:
    >
    > ----------
    > gc: uncollectable <Dog 0x56e10>
    > gc: uncollectable <Cat 0x56e30>
    > gc: uncollectable <dict 0x58300>
    > gc: uncollectable <dict 0x43e40>
    > [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    > {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    > object at 0x56e10>}]
    > -----------
    >
    > Why are there two entries in the list for each uncollectable
    > object(same addresses)? Also, I haven't bound the names "cat" or
    > "dog" anywhere in my program. What do those names mean in the list?
    >

    Read your output carefully!

    gc.garbage is a list of objects. The objects are printed just as they
    would be anywhere else in Python. You've got the dog object, the cat
    object, and the __dict__ of each instance.

    > Doing some further testing, if I eliminate the __del__ methods:
    >
    > -----------
    > import gc
    >
    > class Cat(object):
    > pass
    >
    > class Dog(object):
    > pass
    >
    > def some_func():
    > the_dog = Dog()
    > the_cat = Cat()
    > the_dog.cat = the_cat
    > the_cat.dog = the_dog
    >
    > some_func()
    >
    > gc.set_debug(gc.DEBUG_LEAK)
    > gc.collect()
    > print gc.garbage
    > -------------------
    >
    > I get this output:
    >
    > -----
    > gc: collectable <Dog 0x56e10>
    > gc: collectable <Cat 0x56e30>
    > gc: collectable <dict 0x58270>
    > gc: collectable <dict 0x43e40>
    > [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    > {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    > object at 0x56e10>}]
    > -----
    >
    > The docs say:
    >
    > ---------
    > garbage
    > A list of objects which the collector found to be unreachable but
    > could not be freed (uncollectable objects).
    > --------
    >
    > Since debugging doesn't show any uncollectable objects, why isn't
    > gc.garbage empty? The docs also say:
    >
    > ----
    > garbage
    > ...By default, this list contains only objects with __del__() methods.
    > ----
    >
    > Does set_debug() change the default?
    >


    >From the last line of the documentation block you quoted above: "If

    DEBUG_SAVEALL is set, then all unreachable objects will be added to
    this list rather than freed."
    Chris Mellon, Aug 30, 2007
    #5
  6. 7stud

    7stud Guest

    On Aug 30, 12:36 pm, "Chris Mellon" <> wrote:
    > On 8/30/07, 7stud <> wrote:
    >
    > > On Aug 30, 3:50 am, "Martin v. Löwis" <> wrote:
    > > > > gc.set_debug(gc.DEBUG_LEAK)
    > > > > print gc.garbage

    >
    > > > > --output:--
    > > > > []
    > > > > gc: uncollectable <Dog 0x56e10>
    > > > > gc: uncollectable <Cat 0x56e30>
    > > > > gc: uncollectable <dict 0x58270>
    > > > > gc: uncollectable <dict 0x43e40>

    >
    > > > gc.garbage is filled only after these messages
    > > > are printed, not before. You need to add an explicit
    > > > call to gc.collect() if you want to see what
    > > > uncollectable garbage you have.

    >
    > > > Regards,
    > > > Martin

    >
    > > Hi,

    >
    > > Thanks for the response. I had a cut and paste error in my reply, so
    > > here it is again with the corrections...

    >
    > > Now, if I run the code:

    >
    > > ------------
    > > import gc

    >
    > > class Cat(object):
    > > def __del__():
    > > pass

    >
    > > class Dog(object):
    > > def __del__():
    > > pass

    >
    > > def some_func():
    > > the_dog = Dog()
    > > the_cat = Cat()
    > > the_dog.cat = the_cat
    > > the_cat.dog = the_dog

    >
    > > some_func()

    >
    > > gc.set_debug(gc.DEBUG_LEAK)
    > > gc.collect()
    > > print gc.garbage
    > > -----------

    >
    > > I get this output:

    >
    > > ----------
    > > gc: uncollectable <Dog 0x56e10>
    > > gc: uncollectable <Cat 0x56e30>
    > > gc: uncollectable <dict 0x58300>
    > > gc: uncollectable <dict 0x43e40>
    > > [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    > > {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    > > object at 0x56e10>}]
    > > -----------

    >
    > > Why are there two entries in the list for each uncollectable
    > > object(same addresses)? Also, I haven't bound the names "cat" or
    > > "dog" anywhere in my program. What do those names mean in the list?

    >
    > Read your output carefully!
    >
    > gc.garbage is a list of objects. The objects are printed just as they
    > would be anywhere else in Python. You've got the dog object, the cat
    > object, and the __dict__ of each instance.
    >
    >


    Ah. I missed the braces inside the list, but I still don't understand
    where the names "cat" and "dog" come from.


    > DEBUG_SAVEALL is set, then all unreachable objects will be added to
    > this list rather than freed."


    What is the definition of an "unreachable object"? If I add the
    following:

    -----
    y = Cat()
    del y
    -----

    That object doesn't make it into gc.garbage.
    7stud, Aug 30, 2007
    #6
  7. 7stud

    Chris Mellon Guest

    On 8/30/07, 7stud <> wrote:
    > On Aug 30, 12:36 pm, "Chris Mellon" <> wrote:
    > > On 8/30/07, 7stud <> wrote:
    > >
    > > > On Aug 30, 3:50 am, "Martin v. Löwis" <> wrote:
    > > > > > gc.set_debug(gc.DEBUG_LEAK)
    > > > > > print gc.garbage

    > >
    > > > > > --output:--
    > > > > > []
    > > > > > gc: uncollectable <Dog 0x56e10>
    > > > > > gc: uncollectable <Cat 0x56e30>
    > > > > > gc: uncollectable <dict 0x58270>
    > > > > > gc: uncollectable <dict 0x43e40>

    > >
    > > > > gc.garbage is filled only after these messages
    > > > > are printed, not before. You need to add an explicit
    > > > > call to gc.collect() if you want to see what
    > > > > uncollectable garbage you have.

    > >
    > > > > Regards,
    > > > > Martin

    > >
    > > > Hi,

    > >
    > > > Thanks for the response. I had a cut and paste error in my reply, so
    > > > here it is again with the corrections...

    > >
    > > > Now, if I run the code:

    > >
    > > > ------------
    > > > import gc

    > >
    > > > class Cat(object):
    > > > def __del__():
    > > > pass

    > >
    > > > class Dog(object):
    > > > def __del__():
    > > > pass

    > >
    > > > def some_func():
    > > > the_dog = Dog()
    > > > the_cat = Cat()
    > > > the_dog.cat = the_cat
    > > > the_cat.dog = the_dog

    > >
    > > > some_func()

    > >
    > > > gc.set_debug(gc.DEBUG_LEAK)
    > > > gc.collect()
    > > > print gc.garbage
    > > > -----------

    > >
    > > > I get this output:

    > >
    > > > ----------
    > > > gc: uncollectable <Dog 0x56e10>
    > > > gc: uncollectable <Cat 0x56e30>
    > > > gc: uncollectable <dict 0x58300>
    > > > gc: uncollectable <dict 0x43e40>
    > > > [<__main__.Dog object at 0x56e10>, <__main__.Cat object at 0x56e30>,
    > > > {'cat': <__main__.Cat object at 0x56e30>}, {'dog': <__main__.Dog
    > > > object at 0x56e10>}]
    > > > -----------

    > >
    > > > Why are there two entries in the list for each uncollectable
    > > > object(same addresses)? Also, I haven't bound the names "cat" or
    > > > "dog" anywhere in my program. What do those names mean in the list?

    > >
    > > Read your output carefully!
    > >
    > > gc.garbage is a list of objects. The objects are printed just as they
    > > would be anywhere else in Python. You've got the dog object, the cat
    > > object, and the __dict__ of each instance.
    > >
    > >

    >
    > Ah. I missed the braces inside the list, but I still don't understand
    > where the names "cat" and "dog" come from.
    >


    What happens when you print a dictionary?

    >
    > > DEBUG_SAVEALL is set, then all unreachable objects will be added to
    > > this list rather than freed."

    >
    > What is the definition of an "unreachable object"? If I add the
    > following:
    >


    Anything that the gc would have collected.

    > -----
    > y = Cat()
    > del y
    > -----
    >
    > That object doesn't make it into gc.garbage.


    Because it's already dead. In your previous code, you made dog and cat
    unreachable by virtue of making them a refcycle.

    >
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Chris Mellon, Aug 30, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rob Tillie

    Garbage Collector Debugging

    Rob Tillie, Aug 15, 2003, in forum: ASP .Net
    Replies:
    11
    Views:
    1,729
    JerryK
    Aug 18, 2003
  2. Rimonne

    Garbage Collectionin .NET

    Rimonne, Jan 19, 2004, in forum: ASP .Net
    Replies:
    13
    Views:
    821
    Max-Ph. Blickenstorfer
    Jan 20, 2004
  3. Laser Lu

    Garbage Collection and Manage Code?

    Laser Lu, Jan 26, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    689
    Gaurav Khanna [C# MVP]
    Jan 27, 2004
  4. Thomas Covello
    Replies:
    2
    Views:
    472
    Joe Smith
    Feb 2, 2004
  5. Replies:
    1
    Views:
    426
    mrstephengross
    Jul 25, 2005
Loading...

Share This Page