我无法提供有助于改善内存占用量的完整策略,但我认为这可能有助于分析占用大量内存的确切原因。
如果您查看字典的 Python实现
(这是哈希表的相对简单的实现),以及内置字符串和整数数据类型的实现,例如此处(特别是object.h,intobject
.h,stringobject.h和dictobject.h以及../Objects中相应的* .c文件),您可以准确地计算出预期的空间需求:
一个 整数 是固定大小的对象,即,它包含一个引用计数,一个类型的指针和实际整数,在总通常 至少12个字节 在32位的系统上,并且 24个字节 在64位的系统上,没有考虑到额外的空间可能通过对齐而丢失。
甲 字符串 对象是可变大小的,这意味着它包含
参考计数
类型指针
尺寸信息
延迟计算的哈希码的空间
状态信息(例如用于 插入 字符串)
指向动态内容的指针
总共32位 上至少24个字节 ,或64位上 至少 60个字节 , 不包括字符串本身的空间。
该 词典 本身由多个动叶的,各自含有
当前存储的对象的哈希码(由于使用了冲突解决策略,因此无法从存储桶的位置进行预测)
指向关键对象的指针
指向值对象的指针
总共 在 32位 上至少12个 字节, 在64位上 至少 24个字节 。
- 字典从 8个空存储桶 开始,每当达到其容量时, 通过增加 条目数来 调整 字典的 大小 。
我 在32位计算机上使用46,461个唯一字符串(337,670字节串联的字符串大小)的列表 进行了测试 ,每个字符串都与一个整数相关联-
与您的设置类似。根据上述计算,我希望最小内存占用为
- 46,461 *(24 + 12)字节= 1.6 MB(字符串/整数组合)
- 337670 = 0.3 MB用于字符串内容
- 65,536 * 12字节= 1.6 MB用于哈希存储桶(调整大小13次后)
总共2.65 MB。(对于64位系统,相应的计算结果为5.5 MB。)
空闲运行Python解释器时,根据
ps-tool的占用空间为4.6 MB。因此,创建字典后,预期的总内存消耗约为4.6 + 2.65 = 7.25
MB。 我的测试中的 实际内存占用量(根据
ps)为 7.6 MB。
我想额外的约。Python的内存分配策略(用于内存竞技场等)产生的开销消耗了0.35 MB
当然,现在很多人会指出,我
ps用来测量内存占用量是不准确的,并且我对32位和64位系统上的指针类型和整数大小的假设在许多特定系统上可能是错误的。授予。
但是,尽管如此,我相信 关键结论 是:
- Python 字典实现 消耗的内存非常 少
- 但是许多 int 和(特别是) 字符串对象 (用于引用计数,预先计算的哈希码等)所占用的空间比您最初想的要多
- 有 几乎没有办法避免的内存开销 ,只要您使用Python,并希望表示为单个对象的字符串和整数-至少我看不出怎么能作到
- 寻找(或自己实现) Python-C扩展 可能会值得,该 扩展 实现了将键和值存储为C指针(而不是Python对象)的哈希。我不知道那是否存在。但我相信这是可以做到的,并且可以将内存占用空间减少一半以上。



