You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python列表内存字节分配问题:为何列表内存小于元素内存总和?

核心结论

你猜测的「getsizeof仅返回列表结构自身的内存占用」完全正确,这就是数值看起来不符合直觉的根本原因。

你可以通过以下代码复现测试结果(原示例省略了必要的模块导入):

import sys
intA = 10
A = [x for x in range(0,10)]
print(sys.getsizeof(intA), sys.getsizeof(A))
# 运行输出:28 184

sys.getsizeof()的统计规则

这个函数的统计逻辑非常明确:仅计算传入对象自身直接占用的内存,不会递归统计容器内引用的其他对象的内存。不管是列表、字典、元组这类容器,调用getsizeof时都只会返回容器本身的内存开销,不会把容器里存的元素对象本身的大小算进去。

你测到单个int占28字节是64位CPython的正常表现:CPython的整数是封装后的结构体,除了存储实际数值,还要存引用计数、类型指针等元信息,远大于C语言原生int的内存占比。

184字节的列表内存构成

CPython的列表本质是存储对象指针的动态数组,自身内存分为两部分:

  • 固定头部:64位Python3环境下占40字节,存储引用计数、类型指针、当前列表实际元素长度、元素存储区指针、已分配总容量这几个固定字段。
  • 元素存储区:一块连续内存空间,这里不存实际的整数对象,只存指向整数对象的内存指针,64位系统下单条指针占8字节。

你看到的184字节计算逻辑非常清晰:
184字节 = 40字节固定头部 + 18个指针位 * 8字节/个

之所以10个元素会分配18个指针位,是因为列表作为动态数组,扩容时会预分配冗余空间,避免每次新增元素都重新申请内存、拷贝全量数据,以此保证追加元素操作的均摊O(1)复杂度。你用列表推导生成10个元素的过程中,列表会自动扩容到可容纳18个指针的大小,这部分预分配的冗余空间也会被getsizeof统计到列表自身的占用里。

补充说明

你测试用到的0-9都属于CPython的小整数驻留对象:解释器启动时就会提前创建好-5到256区间内的所有整数,全局唯一复用,不会因为你把这些整数放进列表就额外生成新的整数对象。列表里存的只是指向这些预存整数的指针,整数本身的内存和列表自身的内存是完全独立的两块区域。

如果需要统计列表连带所有内部元素的总内存占用,需要自行递归遍历列表内的所有元素,累加每个对象的内存占用,同时做好循环引用的去重判断,getsizeof本身不提供递归统计能力。


内容的提问来源于stack exchange,提问作者ThreadBucks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 10:30:53