Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected value from sys.getrefcount

Under Python 2.7.5

>>> import sys
>>> sys.getrefcount(10000)
3

Where are the three refcount?

PS: when the 10000 PyIntObject would be Py_DECREF to 0 ref and deallocated? Do not say about gc stuff, reference count itself can work without gc.

like image 373
fengsp Avatar asked Mar 21 '14 03:03

fengsp


1 Answers

  1. When you do something in the REPL console, the string will be compiled internally and during the compilation process, Python creates an intermediate list with the list of strings apart from tokens. So, that is reference number 1. You can check this like this

    import gc
    print gc.get_referrers(10000)
    # [['sys', 'dis', 'gc', 'gc', 'get_referrers', 10000], (-1, None, 10000)]
    
  2. Since its just a numeral, during the compilation process, peep-hole optimizer of Python, stores the number as one of the constants in the generated byte-code. You can check this like this

    print compile("sys.getrefcount(10000)", "<string>", "eval").co_consts
    # (10000,)
    

Note:

The intermediate step where Python stores 10000 in the list is only for the string which is compiled. That is not generated for the already compiled code.

print eval("sys.getrefcount(10000)")
# 3
print eval(compile("sys.getrefcount(10000)", "<string>", "eval"))
# 2

In the second example, we compile the code with the compile function and pass only the code object to the eval function. Now there are only two references. One is from the constant created by the peephole optimizer, the other is the one in sys.getrefcount.

like image 112
thefourtheye Avatar answered Nov 15 '22 13:11

thefourtheye