理解Python内存分配和释放

2024-02-07

我最近遇到本文 http://deeplearning.net/software/theano/tutorial/python-memory-management.html关于python内存分配。

在这个页面中,它描述了 python 的内存使用情况,并且有一个示例显示了整数列表的深度复制。我自己在 Python 2.7 上做了基准测试

Line #    Mem usage    Increment   Line Contents
================================================
     4   28.051 MiB    0.000 MiB   @profile
     5                             def function():
     6   59.098 MiB   31.047 MiB       x = list(range(1000000))  # allocate a big list
     7  107.273 MiB   48.176 MiB       y = copy.deepcopy(x)
     8   99.641 MiB   -7.633 MiB       del x
     9   99.641 MiB    0.000 MiB       return y

所以直接删除 x 只会删除 x 以及所有对 x 的整数的引用,对吧?

这样做也无济于事(那么 del x 和 del x[:] 有什么区别?):

Line #    Mem usage    Increment   Line Contents
================================================
     4   28.047 MiB    0.000 MiB   @profile
     5                             def function():
     6   59.094 MiB   31.047 MiB       x = list(range(1000000))  # allocate a big list
     7  107.270 MiB   48.176 MiB       y = copy.deepcopy(x)
     8   99.637 MiB   -7.633 MiB       del x[:]
     9   99.637 MiB    0.000 MiB       return y

与深层复制相反,如果我使用复制,删除后似乎内存会恢复到新创建 x 时的先前状态

Line #    Mem usage    Increment   Line Contents
================================================
     4   28.039 MiB    0.000 MiB   @profile
     5                             def function():
     6   59.090 MiB   31.051 MiB       x = list(range(1000000))  # allocate a big list
     7   66.895 MiB    7.805 MiB       y = copy.copy(x)
     8   59.262 MiB   -7.633 MiB       del x[:]
     9   59.262 MiB    0.000 MiB       return y

对于字典:

Line #    Mem usage    Increment   Line Contents
================================================
     4   28.051 MiB    0.000 MiB   @profile
     5                             def function():
     6  100.523 MiB   72.473 MiB       x = dict((e, e) for e in xrange(1000000))
     7  183.398 MiB   82.875 MiB       y = copy.deepcopy(x)
     8  135.395 MiB  -48.004 MiB       del x
     9  135.395 MiB    0.000 MiB       return y

对于列表列表(与整数列表相比,我假设 del x 或 del x[:] 只删除堆上的巨大数组列表?):

Line #    Mem usage    Increment   Line Contents
================================================
     4   28.043 MiB    0.000 MiB   @profile
     5                             def function():
     6  107.691 MiB   79.648 MiB       x = [[] for _ in xrange(1000000)]
     7  222.312 MiB  114.621 MiB       y = copy.deepcopy(x)
     8  214.680 MiB   -7.633 MiB       del x[:]
     9  214.680 MiB    0.000 MiB       return y

所以我想问:

  1. 那么如果没有办法收回那些被整数占用的内存呢?整数也是一个对象,对吗?为什么内存根本没有被释放?不能只要求整数吗?或者还有浮动和字符串?对象引用也是如此吗?
  2. 为什么内存有-7 MB?是因为作为数组列表实现的列表从堆中释放了吗?
  3. 无论是list还是dict,del x只能释放数据结构本身(我的意思是数组列表结构,或者dict结构),但是整数、对象引用可以标记为free,但不能返回给系统?

在这个例子中,我该如何释放 x 中的所有下划线列表?

Line #    Mem usage    Increment   Line Contents
================================================
     4   28.047 MiB    0.000 MiB   @profile
     5                             def function():
     6  248.008 MiB  219.961 MiB       x = [list(range(10)) for _ in xrange(1000000)]
     7  502.195 MiB  254.188 MiB       y = copy.deepcopy(x)
     8  494.562 MiB   -7.633 MiB       del x[:]
     9  494.562 MiB    0.000 MiB       return y

TL;DR

del不像 C 中那样释放变量,它只是表示您不再需要它。接下来发生的是实现细节。

基本原理

所以这里发生的事情是del https://docs.python.org/reference/simple_stmts.html#the-del-statement does not释放内存,它只是告诉 python 你已经完成了变量的处理。具体来说:

7.5。德尔声明

del_stmt ::= “del” target_list

删除是递归定义的,与定义赋值的方式非常相似。这里没有详细说明,而是提供一些提示。

删除目标列表会从左到右递归地删除每个目标。

删除名称会从本地或全局命名空间中删除该名称的绑定,取决于该名称是否出现在同一代码块的全局语句中。如果名称未绑定,则会引发 NameError 异常。

属性引用、订阅和切片的删除被传递给所涉及的主要对象;删除切片通常相当于分配正确类型的空切片(但即使这也是由切片对象决定的)。

请注意,没有提到释放内存。相反,你告诉 python 它可以用该内存做“任何它想做的事”。在这种情况下,您的 python 实现(我假设是 CPython)将内存存储在内存缓存中以供以后使用。这使得 python 运行得更快,因为以后不需要分配那么多内存。

Example

考虑这个例子,我们del x然后创建一个副本y再次。请注意,第二次复制期间分配的内存量小于第一次复制期间分配的内存量。这是因为内存被重复使用。如果我们再次这样做,我们会发现在第三次复制期间几乎没有分配任何内存,因为 python 只是重新使用之前分配的内存:

Line #    Mem usage    Increment   Line Contents
================================================
     4   34.777 MiB    0.000 MiB   @profile
     5                             def function():
     6   37.504 MiB    2.727 MiB       x = [list(range(10)) for _ in xrange(10000)]
     7   40.773 MiB    3.270 MiB       y = copy.deepcopy(x)
     8   40.773 MiB    0.000 MiB       del x
     9   41.820 MiB    1.047 MiB       y2 = copy.deepcopy(y)
    10   41.820 MiB    0.000 MiB       del y2
    11   41.824 MiB    0.004 MiB       y3 = copy.deepcopy(y)
    12   41.824 MiB    0.000 MiB       return y

Sources

优秀的“博客”:http://www.evanjones.ca/memoryallocator/ http://www.evanjones.ca/memoryallocator/

http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

理解Python内存分配和释放 的相关文章

  • Python Pocketsphinx:使用 Decoder 类时无法识别关键字

    我正在尝试使用 Pocketsphinx 从 wav 文件中检测关键字 特别是使用解码器类 当我给它的时候this https www filedropper com clientaudio wav 文件并打印它检测到的内容甚至不接近 这是
  • 如何在Python中测量时间?

    我想启动我的程序 测量程序启动的时间 然后等待几秒钟 按下按钮 K RIGHT 并测量按下按钮的时间 我正在使用 Pygame 来注册 Keydown 但在我下面的代码中它没有注册我的 Keydown 我在这里做错了什么 start tim
  • 如何按总和的顺序迭代大量整数元组?

    我在用着itertools combinations http docs python org 2 library itertools html itertools combinations迭代整数元组 我对元组感兴趣最低总和满足一些条件
  • 动态添加字段到数据类对象

    我正在编写一个库来访问 REST API 它返回带有用户对象的 json 我将其转换为 dict 然后将其转换为数据类对象 问题是并非所有字段都是固定的 我想动态添加其他字段 未在我的数据类中指定 我可以简单地为我的对象分配值 但它们不会出
  • 如何访问命令行参数? [复制]

    这个问题在这里已经有答案了 我使用 python 创建项目设置设置 但我需要帮助获取命令行参数 我在终端上尝试过 python myfile py var1 var2 var3 在我的 Python 文件中 我想使用输入的所有变量 Pyth
  • 将文件上传到S3的模拟测试用例

    我们如何模拟文件上传到 S3 我尝试过这样的事情 file mock mock MagicMock spec File name FileMock mock patch storages backends s3boto S3BotoStor
  • Django 星级评定系统和 AJAX

    我正在尝试在 Django 网站上实现星级评级系统 在我的模型中存储评级是排序的 就像在页面上显示分数一样 但我希望用户能够对页面进行评分 基本上从 1 到 5 而无需刷新或更改页面 我发现了以下内容 并且喜欢这里明星的风格 http jv
  • Pandas datetools模块错误

    我正在尝试从 pandas datetools 调用模块 但收到错误消息 指出 mofule 对象没有我所调用的名称的属性 想知道是否有人可以阐明这个问题 下面是我尝试使用的代码 import blpapi import pandas as
  • 如何在 python 中生成可在 C++ 中使用的十六进制转义字符串?

    我正在尝试为使用 MessagePack 的库创建综合单元测试 我想在 python 中创建十六进制转义的二进制字符串 我可以将其嵌入到 C 源代码中 我正在创建一个这样的 In 6 umsgpack packb 0 0 dummy voi
  • 无法在 VS Code 中导入

    我是 python 新手 一直在使用 VS code 现在我正在研究汤普森采样问题 需要 numpy 和 matplotlib 我已经导入了这两个库 但 VS code 给出了无法导入的错误 我知道我必须使用 PIP 进行安装 并且我已经看
  • Django的注释框架和CSRF

    据我了解 Django的评论框架 https docs djangoproject com en 1 4 ref contrib comments 专为匿名公众评论而设计 就像您通常在博客或文章下面看到的那样 换句话说 任何人都可以发表评论
  • Python 类中的继承顺序

    我有课ExampleSim它继承自基类Physics class Physics object arg1 arg1 def physics method print physics method class ExampleSim Physi
  • 使用 tf.keras.Models.Sequential 构建的架构是否比使用 Tensorflow 的功能 API 构建的架构运行得更慢、更准确?

    我只是比较了 2 个 我认为 等效的 VGG ish 架构 一个是使用构建的tf keras Models Sequential 另一个用了Tensorflow 的函数式 API 每个人都试图解决cats vs dogs 数据集 经过 10
  • 从 pandas 数据帧中提取阶段/段以及相应的时间戳

    我有以下数据框 Sleep Stage Time hh mm ss Event Duration s 0 SLEEP S0 23 27 14 SLEEP S0 30 1 SLEEP S0 23 27 44 SLEEP S0 30 2 SLE
  • PyQt4 QPalette 不工作

    btn QtGui QPushButton Button self palettes btn palette palettes setColor btn backgroundRole QtCore Qt green btn setPalet
  • NSAutoreleasePool。什么时候适合创建新的自动释放池?

    在 iOS CocoaTouch 上 我经常看到在方法中创建 NSAutoreleasePool 新实例的代码 我最近在 NSOperation 中看到了一个 设置 NSAutoreleasePool 新实例的基本规则是什么 为什么这比简单
  • 为什么我必须在 pybson (=bson, GitHub:py-bson) 之后安装 pymongo 才能成功导入 pybson?

    编辑 将问题放在网上很长时间后 我注意到这是一个衍生产品无法使用 pymongo 2 2 连接到 MongoDB 2 0 5 数据库 https stackoverflow com questions 10603754 cant conne
  • 一旦相关命令更改,如何自动运行 py.test?

    通过autonose或nosy 一旦某些测试文件或相关文件发生更改 它将自动运行nosetests 请问py test是否提供了类似的功能 有没有其他工具可以自动激发py test 您可以安装pytest xdist 插件 http pyp
  • 以任意深度嵌套 defaultdict

    我想嵌套任意数量的默认字典 如下所示 from collections import defaultdict D defaultdict lambda defaultdict int 正如所描述的那样工作正常earlier https st
  • 在 Raspberry Pi 4 上的多个输出设备上播放多个 mp3 文件

    我需要 4 8 个同时播放立体声音频音乐频道 连续播放 SD 卡上特定文件夹中的 mp3 音乐 Working 板载 3 5 音频插孔 USB声卡正常播放音乐 Problem 但一旦我尝试在树莓派上使用带有 USB 声卡的第三个音频输出 其

随机推荐

  • 将我在提交中更改的行中的空格转换为制表符

    我已经对 git repo 进行了相当大的提交 更改了 60 个文件 插入了 1635 个 删除了 3 个 现在我意识到我使用了空格进行缩进 而其余代码则使用了制表符 因此 我想替换制表符的空格 但仅限于该提交更改的行 因为我不想修改可能使
  • Kube-Proxy-Windows CrashLoopBackOff

    安装过程 我是 Kubernetes 的新手 目前正在 Azure VM 内设置 Kubernetes 集群 我想部署 Windows 容器 但为了实现此目的 我需要添加 Windows 工作节点 我已经部署了一个具有 3 个主节点和 1
  • 通过 Powershell 进行智能图像搜索

    我对按自定义属性搜索文件感兴趣 例如 我想查找具有特定尺寸的所有 JPEG 图像 有些东西看起来像 Get ChildItem Path C Filter jpg Recursive where object Dimension eq 10
  • 同一视图中的普通模型和 IEnumerable 模型

    有一个小问题 我自己解决不了 我想在一个视图中使用相同的模型 但一次使用 IEnumerable 第二次不使用它 My View model IEnumerable
  • Apple Interface Builder:向 UIImageView 添加子视图

    我创建UIImageView在 Interface Bulder 的帮助下 现在我想在其中放置标签 作为其子视图 在代码中我可以输入如下内容 myUIImageView addSubview myUILabel 但我可以在IB的帮助下做到这
  • Java什么时候调用垃圾收集器

    我读了很多关于 Java 堆的文章 我看到如果我们得到 java lang OutOfMemoryError 我们应该增加 Xmx 来解决这个问题 for e g java Xmx2048m Xms256m 这会将 Java 使用的堆内存增
  • 在 Windows 上安装 PG Gem 时出错

    我使用 XAMPP 作为 PostgreSQL 9 3 的安装文件夹 C xampp pgsql 9 3 现在我尝试使用该目录作为参考来安装 PostgreSQL gem gem install pg with pg include C x
  • R 中的“抖动”函数有什么作用?

    根据文档 http astrostatistics psu edu su07 R html base html jitter html 的解释为jitter函数是 向数字向量添加少量噪声 这是什么意思 是否有一个随机数与向量中的每个数字相关
  • 使用 Tkinter 中的按钮终止线程

    在我的 GUI 代码中 我尝试通过单击一个按钮来同时运行循环 1 和循环 2 因此 我用了Thread为了达成这个 但我也尝试通过单击另一个按钮来阻止它 但失败了 在stackoverflow上搜索后发现没有直接杀死的方法Thread 这是
  • Rails 4:f.select 返回字符串而不是整数

    我有用户注册表格 用户必须通过选择选项选择他的国家 地区 当我提交表单时 我收到错误 Country 70309119520500 Expected got String 8039220 请帮助我如何将字符串转换为整数 以便我可以在数据库中
  • OpenGL ES 中使用的 3d 立方体的法线是什么?

    我有一个立方体定义为 float vertices Vertices according to faces 1 0f 1 0f 1 0f Vertex 0 1 0f 1 0f 1 0f v1 1 0f 1 0f 1 0f v2 1 0f 1
  • Visual Studio 2010 中的编程数据断点

    我一直在尝试使用编程数据断点 就像CBreakpoint http www morearty com code breakpoint 例如 通过使用SetThreadContext http msdn microsoft com en us
  • 使用 selenium2library 和 Robot Framework 验证页面中是否存在 2 个文本中的一个文本

    我想测试页面是否包含 TEXT1 或 TEXT2 页面应包含 TEXT1 或 TEXT2 有什么建议我该怎么做 目前我只能检查一篇文本 您可以使用 Page Should Contain Element http rtomac github
  • 列向量与行意味着——与 std::accumulate?

    为了尽可能地懒惰 我在矩阵中读为 vector lt vector
  • 除了动态参数和可选参数之外,C# 4.0 还有哪些新功能?

    所以 C 4 0 昨天出来了 它引入了备受争议的dynamic关键字 命名参数和可选参数 较小的改进是隐含的ref识别 COM 方法上的索引属性和默认属性 逆变和协变 实际上是 NET CLR 功能 不仅仅是 C 以及 真的是这样吗 是dy
  • 找出 Uneaten Leaves 算法错误

    我在面试挑战中遇到了这个问题 K 条毛毛虫正在吃掉 N 片叶子 每条毛毛虫 以独特的顺序从一片叶子落到另一片叶子 所有毛毛虫都开始 在位置 0 处的树枝上 并落在位置之间的叶子上 1 和 N 每条毛毛虫 j 都有一个关联的跳跃数 Aj A
  • 由于延迟加载而使用 Pony ORM 的 DatabaseSessionIsOver?

    我正在使用 Pony ORM 作为烧瓶解决方案 并且遇到了以下问题 考虑以下 db session def get orders of the week self user date q select o for o in Order fo
  • 同步块和监视器对象

    您好 有人可以解释一下下面的代码中的同步代码是否会限制对线程的访问 如果是的话 它与我们使用 this 而不是 msg 作为监视对象有什么不同 public void display String msg synchronized msg
  • 使用 C 中的 GLib/GIO 从 Web 获取文件

    我应该使用什么函数使用 GLib GIO 库从网络获取文件 如果我的文件来自 gchar path http xxx yyyServer sharing temp txt 我应该怎么做才能下载它 对于本地文件 我只使用 fopen 和 fr
  • 理解Python内存分配和释放

    我最近遇到本文 http deeplearning net software theano tutorial python memory management html关于python内存分配 在这个页面中 它描述了 python 的内存使