千家信息网

没有什么内存问题,是一行Python代码解决不了的

发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,内存不足是项目开发过程中经常碰到的问题,我和我的团队在之前的一个项目中也遇到了这个问题,我们的项目需要存储和处理一个相当大的动态列表,测试人员经常向我抱怨内存不足。但是最终,我们通过添加一行简单的代码
千家信息网最后更新 2025年12月01日没有什么内存问题,是一行Python代码解决不了的

内存不足是项目开发过程中经常碰到的问题,我和我的团队在之前的一个项目中也遇到了这个问题,我们的项目需要存储和处理一个相当大的动态列表,测试人员经常向我抱怨内存不足。但是最终,我们通过添加一行简单的代码解决了这个问题。

结果如图所示:

我将在下面解释它的工作原理。
举一个简单的"learning"示例 - 创建一个DataItem类,在其中定义一些个人信息属性,例如姓名,年龄和地址。
小测试--这样一个对象会占用多少内存?
首先让我们尝试下面这种测试方案:
d1 = DataItem("Alex", 42, "-")
print ("sys.getsizeof(d1):", sys.getsizeof(d1))
答案是56字节。看起来比较小,结果令人满意。
但是,让我们检查另一个数据多一些的对象:
d2 = DataItem("Boris", 24, "In the middle of nowhere")
print ("sys.getsizeof(d2):", sys.getsizeof(d2))
答案仍然是56。这让我们明白这个结果并不完全正确。
我们的直觉是对的,这个问题不是那么简单。Python是一种非常灵活的语言,具有动态类型,它在工作时存储了许多额外的数据。这些额外的数据本身就占了很多内存。
例如,sys.getsizeof(" ")返回33,没错,每个空行就多达33字节!并且sys.getsizeof(1)将为此数字返回24-24个字节(我建议C程序员们现在点击结束阅读,以免对Python的美丽失去信心)。
对于更复杂的元素,例如字典,sys.getsizeof(dict())返回272个字节,这还只是一个空字典。举例到此为止,但事实已经很清楚了,何况RAM的制造商也需要出售他们的芯片。
现在,让我们回到回到我们的DataItem类和"小测试"问题。
这个类到底占多少内存?
首先,我们将以较低级别输出该类的全部内容:
def dump(obj):
for attr in dir(obj):
print(" obj.%s = %r" % (attr, getattr(obj, attr)))
这个函数将显示隐藏在"隐身衣"下的内容,以便所有Python函数(类型,继承和其他包)都可以运行。
结果令人印象深刻:

当前位置:技术分享 > 技术参考 > 正文
没有什么内存问题,是一行Python代码解决不了的
2018-12-18 10:24:56 | 编辑:hely | 查看:96 | 评论:0
内存不足是项目开发过程中经常碰到的问题,我和我的团队在之前的一个项目中也遇到了这个问题,我们的项目需要存储和处理一个相当大的动态列表,测试人员经常向我抱怨内存不足。但是最终,我们通过添加一行简单的代码解决了这个问题。
内存不足是项目开发过程中经常碰到的问题,我和我的团队在之前的一个项目中也遇到了这个问题,我们的项目需要存储和处理一个相当大的动态列表,测试人员经常向我抱怨内存不足。但是最终,我们通过添加一行简单的代码解决了这个问题。
结果如图所示:

我将在下面解释它的工作原理。
举一个简单的"learning"示例 - 创建一个DataItem类,在其中定义一些个人信息属性,例如姓名,年龄和地址。

小测试--这样一个对象会占用多少内存?
首先让我们尝试下面这种测试方案:
d1 = DataItem("Alex", 42, "-")
print ("sys.getsizeof(d1):", sys.getsizeof(d1))
答案是56字节。看起来比较小,结果令人满意。
但是,让我们检查另一个数据多一些的对象:
d2 = DataItem("Boris", 24, "In the middle of nowhere")
print ("sys.getsizeof(d2):", sys.getsizeof(d2))
答案仍然是56。这让我们明白这个结果并不完全正确。
我们的直觉是对的,这个问题不是那么简单。Python是一种非常灵活的语言,具有动态类型,它在工作时存储了许多额外的数据。这些额外的数据本身就占了很多内存。
例如,sys.getsizeof(" ")返回33,没错,每个空行就多达33字节!并且sys.getsizeof(1)将为此数字返回24-24个字节(我建议C程序员们现在点击结束阅读,以免对Python的美丽失去信心)。
对于更复杂的元素,例如字典,sys.getsizeof(dict())返回272个字节,这还只是一个空字典。举例到此为止,但事实已经很清楚了,何况RAM的制造商也需要出售他们的芯片。
现在,让我们回到回到我们的DataItem类和"小测试"问题。
这个类到底占多少内存?
首先,我们将以较低级别输出该类的全部内容:
def dump(obj):
for attr in dir(obj):
print(" obj.%s = %r" % (attr, getattr(obj, attr)))
这个函数将显示隐藏在"隐身衣"下的内容,以便所有Python函数(类型,继承和其他包)都可以运行。
结果令人印象深刻:
它总共占用多少内存呢?
在GitHub上,有一个函数可以计算实际大小,通过递归调用所有对象的getsizeof实现。

让我们试一下:

我们分别得到460和484字节,这似乎更接近事实。
使用这个函数,我们可以进行一系列实验。例如,我想知道如果DataItem放在列表中,数据将占用多少空间。
get_size([d1])函数返回532个字节,显然,这些是"原本的"460+一些额外开销。但是get_size([d1,d2])返回863个字节-小于460+484。get_size([d1,d2,d1])的结果更加有趣,它产生了871个字节,只是稍微多了一点,这说明Python很聪明,不会再为同一个对象分配内存。
现在我们来看问题的第二部分。
是否有可能减少内存消耗?
答案是肯定的。Python是一个解释器,我们可以随时扩展我们的类,例如,添加一个新字段:

这是一个很棒的特点,但是如果我们不需要这个功能,我们可以强制解释器使用slots指令来指定类属性列表:

更多信息可以参考文档中的"dictweakref的部分。使用dict所节省的空间可能会很大"。
我们尝试后发现:get_size(d1)返回的是64字节,对比460直接,减少约7倍。作为奖励,对象的创建速度提高了约20%(请参阅文章的第一个屏幕截图)。
真正使用如此大的内存增益不会导致其他开销成本。只需添加元素即可创建100,000个数组,并查看内存消耗:

在没有slots的情况结果为16.8MB,而使用slots时为6.9MB。当然不是7倍,但考虑到代码变化很小,它的表现依然出色。

现在讨论一下这种方式的缺点。激活slots会禁止创建其他所有元素,包括dict,这意味着,例如,下面这种将结构转换为json的代码将不起作用:
def toJSON(self):
return json.dumps(self.dict)
但这也很容易搞定,可以通过编程方式生成你的dict,遍历循环中的所有元素:

向类中动态添加新变量也是不可能的,但在我们的项目里,这不是必需的。

下面是最后一个小测试。来看看整个程序需要多少内存。在程序末尾添加一个无限循环,使其持续运行,并查看Windows任务管理器中的内存消耗。
没有slots

69Mb变成27Mb......好吧,毕竟我们节省了内存。对于只添加一行代码的结果来说已经很好了。
注意:tracemalloc调试库使用了大量额外的内存。显然,它为每个创建的对象添加了额外的元素。如果你将其关闭,总内存消耗将会少得多,截图显示了2个选项:

如何节省更多的内存?
可以使用numpy库,它允许你以C风格创建结构,但在这个的项目中,它需要更深入地改进代码,所以对我来说第一种方法就足够了。
奇怪的是,slots的使用从未在Habré上详细分析过,我希望这篇文章能够填补这一空白。
结论
这篇文章看起来似乎是反Python的广告,但它根本不是。Python是非常可靠的(为了"删除"Python中的程序,你必须非常努力),这是一种易于阅读和方便编写的语言。在许多情况下,这些优点远胜过缺点,但如果你需要性能和效率的最大化,你可以使用numpy库像C++一样编写代码,它可以非常快速有效地处理数据。

内存 问题 字节 结果 项目 测试 代码 对象 数据 函数 元素 动态 一行 程序 答案 存储 内容 字典 类型 处理 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 计算机网络技术题库答案 服务器安装pve还是esxi 网络安全防御技术不包括哪些 做工控软件开发学习什么语言 关系数据库理论中关系的分类 深圳云界直销软件开发 培养软件开发能力的方法 数据库中字符串索引实现 计算机网络技术是美国 50个网吧需要几个服务器 js从文本文档读数据库 网络安全人才要掌握的技术有哪些 网络安全员的自我介绍 如何通过数据库建立本体 浦东新区项目数据库服务商新报价 塔式服务器e330 浙江超频服务器诚信经营 无人智能网络安全防护技术 武昌订制软件开发价格 千万数据库的查询优化 山东顺势网络技术有限公司 广州网络安全公司信安 关于网络安全的好开头 军用综合网络安全防护管理平台 金蝶软件如何导入数据库 uu加速器英国服务器用什么节点 服务器安全备份软件 航空工业出版社计算机网络技术 党中央 网络安全工作 服务器主机不工作怎么办
0