为何列表/元组内存占用小于元素总和?bool与int为何占28字节?
解答:容器内存占用与Python内置对象内存开销问题
先补全你代码里缺失的导入,确保可正常运行:
import sys list_eg = [1,2,3,4,5,"dfd",True,3.1415] tuple_eg = (1,2,3,4,5,"dfd",True,3.1415) print(sys.getsizeof(list_eg)) print(sys.getsizeof(tuple_eg)) # 输出:128 112 print(sys.getsizeof("dfd")) print(sys.getsizeof(3.1415)) print(5*sys.getsizeof(3)) print(sys.getsizeof(True)) # 输出:52 24 140 28 print(52+ 24+ 140+ 28) # 输出:244
一、为什么列表/元组的内存占用小于各元素内存占用总和?
核心原因是Python容器(列表、元组)存储的是对象引用,而非对象本身:
- 在64位系统中,每个对象引用是8字节(本质是指向对象内存地址的指针)。你的列表和元组都有8个元素,仅引用部分就占了
8 * 8 = 64字节。 - 容器本身还有额外的结构开销:
- 列表是可变容器,需要存储当前长度、预留容量(方便快速追加元素)等信息,这部分开销在你的例子里是
128 - 64 = 64字节。 - 元组是不可变容器,不需要预留扩容空间,结构更精简,开销为
112 - 64 = 48字节。
- 列表是可变容器,需要存储当前长度、预留容量(方便快速追加元素)等信息,这部分开销在你的例子里是
- 你计算的
244是所有元素对象本身的内存总和,但sys.getsizeof()返回的容器大小只包含容器自身结构+引用的内存,不包含元素对象的内存。而且像小整数(1-256)、布尔值这类对象是Python预创建的单例,它们的内存是全局共享的,不会因为被容器引用而重复占用。
二、为什么bool类型与整数类型的内存占用是28字节?
Python里的int和bool不是原生基础数据类型,而是完整的Python对象,每个对象都带有额外的元数据开销:
- 每个Python对象都包含
引用计数(8字节,用于垃圾回收)和类型指针(8字节,标记对象类型),这两部分就占了16字节。 - 对于
int对象,还需要存储数字的长度标识(ob_size,4字节)和实际数值(8字节,足够存储小整数),加起来刚好是16 + 4 + 8 = 28字节。 bool是int的子类,True和False本质是预创建的int实例(True等价于1,False等价于0),所以它们的内存大小和int完全一致,也是28字节。
简单来说,Python为了实现动态类型、自动垃圾回收等特性,给每个内置对象都加了额外的结构开销,这就是它比C语言原生int(4字节)大很多的原因。
内容的提问来源于stack exchange,提问作者Inquisitive
相关产品推荐
相关产品推荐

