Python字符串内存分配策略为何不同?列表元组存同串内存更小?
你遇到的这个现象,核心是没搞清楚sys.getsizeof()的统计范围——它只返回调用对象自身的内存占用,不包含该对象引用的其他对象的内存。下面具体拆解:
你的测试代码
import sys print(sys.getsizeof("hello world hello world")) # 输出72 print(sys.getsizeof(["hello world hello world"])) # 输出64 print(sys.getsizeof(("hello world hello world",))) # 输出48
为什么数值看起来“反降”?
单独字符串的72字节:这是字符串对象的全部内存,包含两部分:一是Python字符串对象的固定开销(比如引用计数、类型标识、长度、哈希值、编码信息等),二是字符串本身的字符数据("hello world hello world"共22个ASCII字符,占22字节)。不同CPython版本的固定开销略有差异,最终72字节是内存对齐后的结果。
列表的64字节:这只是列表容器自身的内存,和里面的字符串无关。列表本质是动态数组,它的内存包含自身的结构体开销(引用计数、类型、长度、容量),以及存储元素指针的数组内存。这里列表只存了一个指向字符串的指针(64位系统占8字节),加上列表本身的固定开销,最终对齐后是64字节。如果要算整个列表+字符串的总内存,得把64加上72(若字符串无其他引用),总大小远大于单独的字符串。
元组的48字节:元组是不可变容器,结构比列表更紧凑——它没有列表的“容量”字段(因为不可变,不需要预分配空间),所以自身开销更小。同样,这48字节只是元组容器的内存,里面只存了一个指向字符串的指针,总内存为48+72,远大于单独字符串。
总结
你看到的数值不是同一维度的:单独字符串的数值是它自身的全部内存,而列表、元组的数值只是容器自身的大小,不包含它们指向的字符串的内存。两者没有直接可比性,容器的总内存(容器+字符串)其实比单独字符串大得多。
内容的提问来源于stack exchange,提问作者krupesh Patel

