64位机器下Python整数与浮点数内存管理及占用疑问
这问题挺有意思的,我之前也琢磨过Python里数值类型的内存占用,结合CPython的底层实现来给你拆解清楚:
Python对整数与浮点数的内存管理逻辑
先明确核心前提:Python里的所有数值都是对象,不是C语言那种原生基本类型,所以内存占用会包含对象本身的元数据,这是理解大小差异的关键。
一、整数(int)的内存结构与大小变化
CPython里的整数用PyLongObject结构体实现,在64位系统下,这个结构体的基础组成是:
ob_refcnt:引用计数,追踪这个对象被多少地方引用,占8字节ob_type:指向整数类型对象的指针,占8字节ob_size:标记整数的位数(正数表示正整数,负数表示负整数),占8字节
这三部分加起来正好24字节,也就是你调用getsizeof(int())和getsizeof(0)返回24的原因——当整数是0时,ob_size为0,不需要额外空间存储数字本身,总大小就是基础的24字节。
那为什么getsizeof(1)返回28呢?因为PyLongObject还包含一个可变长度的数组ob_digit,用来存储整数的实际数值(每个单元是32位的无符号整数,占4字节)。当整数是1时,ob_size为1,需要一个ob_digit单元来存这个值,所以总大小就是24 + 4 = 28字节。如果是更大的整数(比如超过32位的数值),ob_digit会自动扩展,内存占用也会随之增加。
二、浮点数(float)的内存结构
CPython的浮点数用PyFloatObject结构体实现,结构比整数简单很多:
ob_refcnt:同样是引用计数,占8字节ob_type:指向浮点数类型对象的指针,占8字节ob_fval:一个double类型变量,直接存储浮点数的实际数值,占8字节
这三部分加起来正好24字节,而且不管浮点数是0.0、1.5还是更大的数值,这个结构体的大小都是固定的——因为double本身就能覆盖所有标准浮点数的存储需求,不需要可变长度的额外空间。这就是为什么getsizeof(1.5)返回24,比整数1的28字节小的原因。
核心差异总结
- 整数是可变长度对象:根据数值大小动态调整存储数值的空间,基础大小24字节,数值越大占用内存越多
- 浮点数是固定长度对象:无论数值是什么,都用一个
double存储,总大小固定为24字节
内容的提问来源于stack exchange,提问作者0x5961736972




