Python对象id现象解析:不可变与可变对象的内存机制
不可变与可变对象的内存地址机制解析
环境
Python 3.8 CPython(Windows 10系统)
案例1
代码:
print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss')) print(id('sss'))
输出:
2343368851504 2343368851504 2343368851504 2343368851504 2343368851504 2343368851504 2343368851504 2343368851504 2343368851504 2343368851504 2343368851504 2343368851504
说明:
多次打印不可变对象的内存地址,结果完全一致。
案例2
代码:
print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5])) print(id([1, 2, 3, 4, 5]))
输出:
2343339032320 2343339036864 2343339032512 2343339037568 2343339032320 2343339036864 2343339032512 2343339037568 2343339032320 2343339036864
说明:
多次打印可变对象的内存地址,地址呈周期性重复,每4个为一个循环。
问题
上述现象背后的机制是什么?
解答
- 对于
小整数或驻留字符串(interned strings)这类不可变对象,CPython会出于性能优化目的复用相同值的对象,因此每次调用id()返回的内存地址完全一致。 - 针对列表这类可变小对象,CPython采用**内存池(memory pooling)**技术分配内存:内存池由预分配的固定大小内存块构成,创建对象时直接从池内的可用块分配内存;当对象被销毁后,对应的内存块会被放回池中等待复用,这就导致了内存地址出现周期性重复的规律。
- 这类现象和
id()方法本身无关,它只是如实返回对象当前的内存地址。
内容的提问来源于stack exchange,提问作者Arthur
相关产品推荐
相关产品推荐

