社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python-为什么不可变的对象不占用相同的内存

Adrian • 8 年前 • 2308 次点击  

我用的是微丝,但没关系

>>> b = [None]*40
>>> gc.collect(); gc.mem_free(); dir(); sys.modules
101
7008
['sys', '__name__', 'a', 'gc', 'b']
{}
>>> for i in range(40):
...     b[i] = (255, 0, 0)
...     gc.collect(); gc.mem_free();
...
...
...
5
6800
0
6768
0
6736
0
6704
0
6672
0
6640
0
6608
0
6576
0
6544
0
6512
0
6480
0
6448
0
6416
0
6384
0
6352
0
6320
0
6288
0
6256
0
6224
0
6192
0
6160
0
6128
0
6096
0
6064
0
6032
0
6000
0
5968
0
5936
0
5904
0
5872
0
5840
0
5808
0
5776
0
5744
0
5712
0
5680
0
5648
0
5616
0
5584
0
5552
>>>

小数字是对象的数量 gc.collect() 收集和大量的是有多少可用内存。

(255, 0, 0) 是一个不可变的元组,它包含不可变的对象,所以为什么每次赋值后可用内存量都会减少?

如果一个对象是不可变的,那么Python复制它有什么意义呢?
为什么不把相同的“指针”分配给每个 b[i] ?

更新

我在元组中使用了更大的数字 (55555555555555555555, 55555555555555555555) 内存的使用也是一样的。

    >>> gc.collect(); gc.mem_free(); dir(); sys.modules
5
6368
['sys', '__name__', 'gc', 'i']
{}
>>> b = [None]*40
>>> for i in range(40):
...     b[i] = (55555555555555555555,55555555555555555555)
...     id(b[i])
...     gc.collect(); gc.mem_free()
...
...
...
5347968
10
5824
5347136
0
5808
5347312
0
5792
5347456
0
5776
5347536
0
5760
5347552
0
5744
5347696
0
5728
5347712
0
5712
5347984
0
5696
5348176
0
5680
5348192
0
5664
5348208
0
5648
5348224
0
5632
5348240
0
5616
5348256
0
5600
5348272
0
5584
5348288
0
5568
5348608
0
5552
5348640
0
5536
5348656
0
5520
5348672
0
5504
5348688
0
5488
5348704
0
5472
5348720
0
5456
5348736
0
5440
5348848
0
5424
5348864
0
5408
5348880
0
5392
5348896
0
5376
5348912
0
5360
5348928
0
5344
5348944
0
5328
5349104
0
5312
5349120
0
5296
5349136
0
5280
5349152
0
5264
5349168
0
5248
5349184
0
5232
5349200
0
5216
5349216
0
5200
>>>

但是当我使用整数时 (55555555555555555555) ,内存使用不会随着迭代而改变。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30653
文章 [ 1 ]  |  最新文章 8 年前
ShadowRanger
Reply   •   1 楼
ShadowRanger    8 年前

因为广义实习 全部的 解释器中不可变的对象是复杂的,并且添加了大量的代码,这些代码很少能保存任何有价值的东西。

也就是说,你的代码 做 使用 tuple 在cpython参考解释器上。这是一个实现细节,所以每个解释器都可以在这里做出自己的决定,我猜微丝盒并没有选择这样做(可能是为了让解释器足够简单,能够在较弱的硬件上运行)。

看起来Micropython执行缓存 int 常量,但不适用于 元组 S; 元组 s很难处理(至少在最初,cpython没有在主a s t阶段执行此操作,它只是对生成的字节代码运行一个窥视孔优化器来转换 LOAD_CONST 其次是 BUILD_TUPLE 仅使用 装入常数 结果到 装入常数 结果的 元组 )并且所涉及的额外工作可能被认为是不值得的。