Objects and memory in python
I read this medium article on python memory management. It led me down a little, python data types and memory rabbit hole. Thinking back to CS-101 class you learn about two kinds of objects, mutable and immutable. In python they are:
Immutable Object: int, float, long, complex, string tuple, bool
Mutable Object: list, dict, set, byte array, user-defined classes
I'll be referencing CPython, not other implementations like PyPy.
When investigating how things are working under the hood, id() is an invaluable. This function returns the memory address of the object. No two objects have the same identity. But as you'll see, two variables can reference the same object.
Along with id(), is returns whether variables reference the same object. This is different from the equality operator ==.
Python variables work a lot like pointers in other languages. They refer to a value stored somewhere in memory. If it is a mutable object and the value changes the memory location changes:
>>> x = 9999
>>> y = 9999
>>> z = x
x and z reference the same memory location (notice that even though x and y are the same value, 9999, they are stored in different memory locations)
>>> id(x), id(y), id(z)
(4426537648, 4426537712, 4426537648)
Now let's change the value of x. You might think because we set z = x that z will now equal x's new value, but that's not the case.
>>> x = 10000
>>> x, y, z
(10000, 9999, 9999)
>>> id(x), id(y), id(z)
(4426537840, 4426537712, 4426537648)
Z still references the original memory location because it hasn't changed, it still points at the memory location (4426537648) that holds 9999. When you assign a new value to x, you are really reserving a new memory location(4426537840) and storing your new value (1000) in there, then pointing to that location with x. Now if z still wasn't referencing the original memory location python's garbage collector would see that and free it up.
Okay, makes sense right? Now lets try that again.
>>> x = 2
>>> id(x)
4423535824
>>> y = x
>>> id(y)
4423535824
>>> z = 2
>>> id(z)
4423535824
>>> z, y, z
(2, 2, 2)
Woah woah woah, what happened here?
One weird thing with this. CPython keeps objects for all integers between -5 and 256. So if you an integer in that range, python simply references the existing object. Same goes for short strings. They won't get garbage collected like others.
Comments
Post a Comment