Issue
I recently learned that when you delete a list in Python, the reference of this list gets saved up within an array and gets popped out when you initialize a new list.
I ran this in my regular interpreter:
l = [1,2,3]
l_id = id(l)
del l
g = [1,2,3]
id(g) == l_id # True
And as expected I got the right result.
I tried the same thing on my IPython interpreter, and got False
instead. Why does it happen? Is it better?
Python version: v3.7.0:1bf9cc5093
Ipython version: 7.5.0
Update
Its happend also with different lists:
l = [1,2,3]
l_id = id(l)
del l
g = [1,2,3,4,5,6,7,8]
id(g) == l_id # True
And its always happend, its not just a random thing that they gets the same reference
Update 2
I do know why this happend, i just want to know why its happend only on pure python interpreter and not on my ipython, and which one of those method is better for memory management
Update 3
As i can explain the reason that those list have the same id, i can not get why it is difference between ipython and python.
Look at the implemetation of List listobject.c.
As we can see there is an array of references, called free_list
. which the values of the array is the destroyed list objects, and the count numfree
for the array indexing. we can see that if there is more then 80 list deleted, the next one wont be saved in the array. so from those line we can say that my statement can be always true for any new python interpreter.
but i still can not find a reason for ipython to work like this
Solution
First, id()
doesn't have anything to do with general memory management in Python the language. However, in CPython (hence the IPython REPL) it has a one-to-one correspondence with raw memory locations. Some comments pointed out that the question doesn't necessarily make sense in the abstract, but restricted to IPython and the standard CPython REPL it seems applicable.
All that's happening is that in the processing of your cell block the IPython environment creates a few extra objects (including list objects) behind the scenes. Since the original memory space from l
is taken for some of the lists that IPython created behind the scenes, the CPython allocator finds a new block of memory for g
.
For some evidence of the extra objects, consider the following experiment run in both CPython and IPython that introspects the garbage collector.
from gc import get_objects
orig = set(map(id, get_objects()))
l = [1,2,3]
l_id = id(l)
del l
g = [1,2,3]
final = set(map(id, get_objects()))
len(orig.symmetric_difference(final)) # 2 in CPython, 6-40+ in IPython
Answered By - Hans Musgrave
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.