2

In python suppose one does the following:

# var is a variable, ClassName is the name of a class

var = ClassName(<params...>) # instatiate class to var 
var = ClassName(<params...>) # reset variable to new instance

# or in loop

while 1:
    var = ClassName(<params...>)
    # use var ...

My question is, when does the previous instance get garbage collected? Does it happen before or after the next instance is created?

Gabriel Ratener
  • 595
  • 5
  • 20

2 Answers2

4

Keep in mind (periodic) garbage-collection and reference-counting are two different mechanisms. In your case, ref-counting is the relevant one.

Objects whose ref-count becomes zero get deallocated immediately (no need to wait for the periodic gc to run).

[as @delnan pointed out, ref-counting is not an official python "feature", but rather an implementation detail of CPython specifically. Nevertheless, it is worth knowing about]

In your case, You get two concurrent existing objects. This is the order things happen:

a new object is created, and is referenced by name "var"
[you now have one existing object]
while True:
    a new object is created
    [you now have two existing objects]
    it is referenced by name "var" (refcount += 1)
    old object is no longer referenced by name "var" (refcount -= 1)
    old object's refcount is now 0, it gets deallocated
    [you now have one existing object]

If you want only one concurrent object to exist, you can add del var as the first line in your loop.

shx2
  • 61,779
  • 13
  • 130
  • 153
  • There are many who argue refcounting is a kind of garbage collection, and they have a point. You are of course right to distinguish, but saying one is a GC and the other isn't introduces an unnecessary dichotomy. Also: The whole refcounting business is merely a CPython implementation detail, it's just as valid to use tracing GC for everything. It's just as easy (and IMHO more generally useful) to just think in terms of reachability - it doesn't change the answer either. –  Jun 03 '14 at 20:57
  • @delnan right, I generally agree with your comment. However I do think that in some (uncommon?) cases it helps to know which of the mechanisms kicks in. It might not change the answer to the "before or after?" question, but it changes the answer to a slightly more general "how many concurrent objects?" question. With no ref-counting, you can end up with many, while with rc, you get only two. – shx2 Jun 03 '14 at 21:04
  • Yes, that is true. But on the other hand, relying on knowledge of RC for any functionality (in particular, assuming there will be only two objects e.g. to simplify resource management) makes code fragile on other implementations and in the presence of cycles. It's mostly interesting for hacking on CPython or debugging memory issues (or pure curiosity of course), not so much useful for programming. –  Jun 03 '14 at 21:06
  • @delnan I also edited some phrasing to make it more in line with your comment. – shx2 Jun 03 '14 at 21:07
  • @delnan (again, not disagreeing with you at all) as I read the question, it is about better understanding language's internals (wehter to rely on them or not is a different story). providing an answer which abstracts the details away feels like missing the point to me... – shx2 Jun 03 '14 at 21:12
  • I agree that refcounting is worth knowing about, and discussing. I just don't think any introduction to it should go without mentioning that it's an implementation detail and other Pythons diverge from it. –  Jun 03 '14 at 21:14
1

After. If it happened before, and then creation of the new instance failed with an exception, the variable would be left in some weird state, uninitialized or referring to garbage. Hypothetically, a more intelligent Python implementation might collect the old object in advance if it can prove that the new object's creation will work and the old object is no longer needed.

user2357112
  • 260,549
  • 28
  • 431
  • 505