Python应用专题 | 11:如何释放字典的内存占用?

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
大数据开发治理平台 DataWorks,不限时长
简介: 构建一个大字典,并往其中增减元素,但是发现整体的内存消耗并没有因此而维持稳定状态,而是不断增加。本文尝试定位该问题,并解决。

背景

构建一个大字典,并往其中增减元素,但是发现整体的内存消耗并没有因此而维持稳定状态,而是不断增加。

问题解析

Python中的字典,只有不再使用的时候才会释放对应的内存。在使用 pop 或者 delete 删除字典中的item(或者说entry)后,为了保证hash table 探测链的完整,那个被删除的entry只是被标记成了空,并没有真正被删除掉,所以该字典的内存占用没有得到释放。这是为了避免多度重建hash table。

释放内存

那如何释放字典的内存?现已知的方案是创建或者拷贝一个旧字典再覆盖掉新字典。具体示例如下:

import sys
import gc
import copy
a = {}
print("init empty dict memory size={} bytes".format(sys.getsizeof(a)))

for i in range(10**6):
    a[i] = i
print("after set value, dict memory size={} bytes".format(sys.getsizeof(a)))

for i in range(10**6):
    del a[i]
    # a.pop(i)

print("after del, dict memory size={} bytes".format(sys.getsizeof(a)))
a_new = dict(a)
print("after init a new one, dict memory size={} bytes".format(sys.getsizeof(a_new)))
b = copy.copy(a)
print("after copy a new one, dict memory size={} bytes".format(sys.getsizeof(b)))
c = copy.deepcopy(a)
print("after deepcopy a new one, dict memory size={} bytes".format(sys.getsizeof(c)))

运行结果如下:

init empty dict memory size=240 bytes
after set value, dict memory size=41943144 bytes
after del, dict memory size=41943144 bytes
after init a new one, dict memory size=240 bytes
after copy a new one, dict memory size=240 bytes
after deepcopy a new one, dict memory size=240 bytes

字典clear操作后的内存占用比完全新建的时候小?

在实验过程发现,字典调用 clear 操作后的内存占用比新建一个字典的内存占用小。示例如下:

dict = {}
print(sys.getsizeof(dict))  # 240, 这因为新的字典的 size 是 PyDict_MINSIZE
dict.clear()
print(sys.getsizeof(dict))  # 72

image.png

这是因为新建dictionary是按照PyDict_MINSIZE 分配keyspace。当调用.clear()函数后,keyspace 被重新分配到一个静态的空keyspace: Py_EMPTY_KEYS,此时的dictionary是真的empty。

相关文章
|
15小时前
|
存储 缓存 数据库
Python中字典
Python中字典
|
15小时前
|
Python
使用Python构建一个简单的Web应用
使用Python构建一个简单的Web应用
5 1
|
15小时前
|
IDE 开发工具 C++
|
1天前
|
搜索推荐 数据可视化 Python
Python应用实战,用动画生成冒泡排序的过程
冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
|
1天前
|
存储 安全 Python
Python 遍历字典的这6种方法,你都掌握了吗
Python提供了多种遍历字典的方法,可以根据实际需要选择合适的方法。无论是需要单独访问键或值,还是同时需要键和值,Python的字典都提供了简单而有效的方式来处理这些需求。
|
1天前
|
监控 安全 网络安全
网络安全与信息安全:防护之道与加密技术构建高效Android应用:从基础到高级的内存优化策略
【5月更文挑战第27天】在数字化时代,数据成为了新的货币。然而,随着信息技术的蓬勃发展,网络安全漏洞和信息泄露事件层出不穷,对个人隐私和企业安全构成了严重威胁。本文将深入探讨网络安全的重要性,分析当前常见的网络攻击方式,并重点分享关于加密技术和提升安全意识的知识。通过阅读本文,读者将获得如何有效防御网络威胁、保护个人和企业信息安全的策略。
|
1天前
|
存储 缓存 算法
深入理解操作系统内存管理:分页系统的优势与挑战构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第27天】 在现代计算机系统中,内存管理是操作系统的核心功能之一。分页系统作为一种内存管理技术,通过将物理内存划分为固定大小的单元——页面,为每个运行的程序提供独立的虚拟地址空间。这种机制不仅提高了内存的使用效率,还为多任务环境提供了必要的隔离性。然而,分页系统的实现也带来了一系列的挑战,包括页面置换算法的选择、内存抖动问题以及TLB(Translation Lookaside Buffer)的管理等。本文旨在探讨分页系统的原理、优势及其面临的挑战,并通过分析现有解决方案,提出可能的改进措施。
|
1天前
|
Python
Python应用中语法不正确的缩进
【5月更文挑战第17天】
6 1
|
1天前
|
IDE 开发工具 C++
|
1天前
|
IDE 开发工具 C++
Python应用中语法拼写错误
【5月更文挑战第17天】
15 4