numpy.ndarray 对象不被垃圾回收

2024-05-04

在尝试微调某些 C/C++ 函数的 Python 绑定中的一些内存泄漏时,我发现了一些与 Numpy 数组的垃圾收集相关的奇怪行为。

为了更好地解释这种行为,我创建了几个简化的案例。该代码是使用memory_profiler,其输出紧随其后。当涉及到 NumPy 数组时,Python 的垃圾收集似乎没有按预期工作:

# File deallocate_ndarray.py
@profile
def ndarray_deletion():
    import numpy as np
    from gc import collect
    buf = 'abcdefghijklmnopqrstuvwxyz' * 10000
    arr = np.frombuffer(buf)
    del arr
    del buf
    collect()
    y = [i**2 for i in xrange(10000)]
    del y
    collect()

if __name__=='__main__':
    ndarray_deletion()

通过以下命令我调用了memory_profiler:

python -m memory_profiler deallocate_ndarray.py

这就是我得到的:

Filename: deallocate_ndarray.py
Line #    Mem usage    Increment   Line Contents
================================================
 5   10.379 MiB    0.000 MiB   @profile
 6                             def ndarray_deletion():
 7   17.746 MiB    7.367 MiB       import numpy as np
 8   17.746 MiB    0.000 MiB       from gc import collect
 9   17.996 MiB    0.250 MiB       buf = 'abcdefghijklmnopqrstuvwxyz' * 10000
10   18.004 MiB    0.008 MiB       arr = np.frombuffer(buf)
11   18.004 MiB    0.000 MiB       del arr
12   18.004 MiB    0.000 MiB       del buf
13   18.004 MiB    0.000 MiB       collect()
14   18.359 MiB    0.355 MiB       y = [i**2 for i in xrange(10000)]
15   18.359 MiB    0.000 MiB       del y
16   18.359 MiB    0.000 MiB       collect()

我不明白为什么即使是强迫打电话collect不要通过释放一些内存来减少程序的内存使用量。此外,即使 Numpy 数组由于底层 C 构造而无法正常运行,为什么列表(纯 Python)不会被垃圾收集呢?

我知道del不直接调用底层__del__方法,但你会注意到所有del代码中的语句实际上最终将相应对象的引用计数减少到零(从而使它们有资格进行垃圾收集)。通常,当对象经历垃圾回收时,我希望在增量列中看到负条目。谁能解释一下这里发生的事情吗?

注意:此测试在 OS X 10.10.4、Python 2.7.10 (conda)、Numpy 1.9.2 (conda)、Memory Profiler 0.33 (conda-binstar)、psutil 2.2.1 (conda) 上运行。


为了查看回收的内存垃圾,我必须将 buf 的大小增加几个数量级。也许尺寸太小,不适合memory_profiler检测变化(它查询操作系统,因此测量不是很精确),或者可能它太小,Python 垃圾收集器无法关心,我不知道。

例如,将因子中的 10000 替换为 100000000buf yields

Line #    Mem usage    Increment   Line Contents
================================================
21   10.289 MiB    0.000 MiB   @profile
22                             def ndarray_deletion():
23   17.309 MiB    7.020 MiB       import numpy as np
24   17.309 MiB    0.000 MiB       from gc import collect
25 2496.863 MiB 2479.555 MiB       buf = 'abcdefghijklmnopqrstuvwxyz' * 100000000
26 2496.867 MiB    0.004 MiB       arr = np.frombuffer(buf)
27 2496.867 MiB    0.000 MiB       del arr
28   17.312 MiB -2479.555 MiB       del buf
29   17.312 MiB    0.000 MiB       collect()
30   17.719 MiB    0.406 MiB       y = [i**2 for i in xrange(10000)]
31   17.719 MiB    0.000 MiB       del y
32   17.719 MiB    0.000 MiB       collect()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

numpy.ndarray 对象不被垃圾回收 的相关文章

随机推荐

  • 如何对德语文本进行词形还原?

    我有一篇德语文本 我想对其应用词形还原 如果不可能进行词形还原 那么我也可以接受词干提取 Data 这是我的德语文本 mails Hallo Ich spielte am fr hen Morgen und ging dann zu ein
  • 在自引用表中查询父项和子项

    我有一个Comments如下表所示 在MySQL content created at id parent id second comment 2014 06 03T10 08 44 0000 37 1 third comment 2014
  • 按降序对数字进行排序

    我有 20 个文本框 每个都包含一个特定的数字 我希望 textbox1 到 textboxN 的数字按降序排列 如果任何文本框的值为零 那么我想保留该文本框不变 需要 vb net 中的示例代码 用于按降序对元素进行排序 dim arra
  • Pandas 滚动 std 会产生不一致的结果并且与 value.std 不同

    使用 pandas v1 0 1 和 numpy 1 18 1 我想计算时间序列上不同窗口大小的滚动平均值和标准差 在我正在处理的数据中 某些后续点的值可以是恒定的 这样 根据窗口大小 滚动平均值可能等于窗口中的所有值 并且相应的 std
  • Tensorflow:从 TFRecords 文件中提取图像和标签

    我有一个 TFRecords 文件 其中包含图像及其标签 名称 大小等 我的目标是将标签和图像提取为 numpy 数组 我执行以下操作来加载文件 def extract fn data record features Extract fea
  • 在多分支管道中授予复制 artIfact 权限

    我有以下设置 通过配置的 Jenkins 多分支管道作业Jenkinsfile 成功签出和构建后 工件将被存档 并触发下游作业来部署生成的工件 为了让第二个工作能够通过 class CopyArtifact 步骤 它需要复制权限 所以问题是
  • 如何在AWS中将AMI从爱尔兰区域复制到中国区域

    我在 AWS 爱尔兰区域有一个设置 现在我希望在中国使用该 AMI 有谁知道完成任务的最佳实践是什么 任何帮助将不胜感激 提前致谢 中国地区目前不支持 AMI 复制 根据AWS 将 AMI 从美国传输或复制到中国 北京 https foru
  • Django 删除确认视图显示变量名称而不是信息

    谁能帮我解决以下场景 我有 3 张桌子 如下所示 1和2是我的数据表 并且 3 与 1 和 2 保持关系 1 Qa table ID QA 1 qa1 2 qa2 3 qa3 a field of my Qa model tags sele
  • 如何覆盖/更新当前由 IIS 提供服务的文件?

    问题 我的公司每月发布一份时事通讯 我将其托管在我们的内部网站上 我有一个供时事通讯作者上传最新版本的页面 作者上传最新的新闻通讯后 他会发送一封广播电子邮件来宣布新的新闻通讯 员工总是会检查新的时事通讯并向作者发送反馈以及需要进行的更正
  • 如何将大型 XML 字符串插入 Oracle 表中?

    我想将一个大的 XML 字符串插入到我的表中 我的表是 test id xml column XMLType 当我插入值时 它返回 字符串文字太长 错误 我上网查了一下 大家都说把数据类型改成CLOB 但我想存储相同的数据类型 XMLTyp
  • 如何确保参数仅指向静态存储期间的对象?

    我想确保赋予函数的参数指向 或引用 一个对象 该对象具有静态存储时间 class 该解决方案需要与 C 11 一起使用 而无需编译器特定的扩展 我在研究过程中发现的最相似的问题是仅限于C语言的一种 https stackoverflow c
  • 世界CF。服务通用方法

    如何在 wcf 服务中使用通用方法 我写了这段代码 OperationContract void AddItem
  • 什么是 scanf("%*s") 和 scanf("%*d") 格式标识符?

    格式的实际用途是什么 在 scanf 中 如果这种格式存在 那么它背后一定有某种目的 下面的程序给出了奇怪的输出 include
  • 同步迭代 javascript 对象

    我有一个像这样的对象 let myObject db1 db1 file1Id db1 file2Id db 1file3Id db2 db2 file1Id db2 file2Id 我遍历这个对象并在每次迭代中 我连接到数据库 检索文件
  • jcop是在java卡中安装小程序的唯一方法吗?

    我正在尝试理解java卡的概念 我有一些疑问 我想与大家分享 也许你会对我有任何最好的建议 Jcop 我在某处读到 Java Card OpenPlatform JCOP 是由 IBM Z rich Research Laboratory
  • java运算符“->”的含义[重复]

    这个问题在这里已经有答案了 下面的代码取自 SpringBoot 应用程序的初始化 java 运算符 gt 的含义是什么 Bean public EmbeddedServletContainerCustomizer containerCus
  • 在 hibernate JPA 的 getReference() 之后,如果不使用 setter 发出 select 则无法更新

    我有以下方法 Transactional public void savethis EntityObject t entityManagerTreasury getReference EntityObject class 1 t setAc
  • webapp 在 iOS 7 中无法正确缩放

    有人遇到同样的问题吗 content width device width 当我的 iphone 仍然是 i0S 6 并且我刚刚更新到 iOS 7 并且似乎不再工作时它就可以工作 或者可能是其他原因导致了问题 有人有什么想法吗 现在我正在使
  • GSON 没有为接口类型调用我的 TypeAdapter

    GSON 似乎在使用某种技巧 它查看 JavaBean 的内部字段 而不是使用可公开访问的属性信息 不幸的是 这对我们来说不会成功 因为我们神奇地创造的豆子充满了我不希望它存储的私人领域 Test public void testJson
  • numpy.ndarray 对象不被垃圾回收

    在尝试微调某些 C C 函数的 Python 绑定中的一些内存泄漏时 我发现了一些与 Numpy 数组的垃圾收集相关的奇怪行为 为了更好地解释这种行为 我创建了几个简化的案例 该代码是使用memory profiler 其输出紧随其后 当涉