【问题标题】:Python del statementPython del 语句
【发布时间】:2013-02-04 20:34:37
【问题描述】:

在 Python 中对变量调用 del。这会立即释放分配的内存还是仍在等待垃圾收集器收集?就像在 java 中一样,显式调用 del 对何时释放内存没有影响。

【问题讨论】:

  • 垃圾回收的重点是不用担心内存什么时候被释放。那你为什么要担心呢?
  • 我正在处理大量流量并观察到内存泄漏问题。我几乎可以肯定问题不在 python 脚本中,而只是试图确定。

标签: python garbage-collection del


【解决方案1】:

关于删除: 有时您必须处理大型数据集,其中必须计算内存密集型操作并以递归方式将大量数据存储到变量中。为了节省 RAM,当您完成整个操作时,如果您不再在递归循环之外使用它,则应该删除该变量。你可以使用命令

del varname 后跟 Python 的垃圾收集器 gc.collect()

关于速度: 在具有监管要求的金融应用等应用中,速度是最重要的。您必须确保在预期的时间范围内完成操作的速度。

【讨论】:

    【解决方案2】:

    另外,del 语句 似乎比 assigning None 快一点(类似于 Java 的风格 assigning null 给一个变量释放它的内存...)。

    比较:

    import time, math
    
    def measure_del():
            start = time.time()
            for i in range(0,int(math.pow(10,8))):
                        a = "123"
                        del a # <--- !!!
            end = time.time()
            print(end-start)
    
    def measure_none():
            start = time.time()
            for i in range(0,int(math.pow(10,8))):
                        a = "123"
                        a = None # <--- !!!
            end = time.time()
            print(end-start)
    

    导致(在 idle3.4 中运行):

    >>> measure_del()
    3.9930295944213867
    >>> measure_del()
    3.7402305603027344
    >>> measure_del()
    3.8423104286193848
    >>> measure_del()
    3.753770351409912
    >>> measure_del()
    3.7772741317749023
    >>> measure_del()
    3.815058946609497
    
    >>> measure_none()
    4.052351236343384
    >>> measure_none()
    4.130320072174072
    >>> measure_none()
    4.082390069961548
    >>> measure_none()
    4.100180625915527
    >>> measure_none()
    4.071730375289917
    >>> measure_none()
    4.136169672012329
    

    【讨论】:

    • 为什么程序员如此着迷于对程序整体速度没有影响的事物的速度? :)
    • 嗯,它就像一包纸。例如。您可以购买 500 张,克重为 80g/m² 或 90g/m²。如果你写在一张纸上,你几乎不会注意到有什么不同。但是,如果您比较这两种包装,您会发现在高度、重量和价格方面存在明显差异。编写好的代码,平衡代码的可读性和机器级别的性能当然不是一个坏主意。
    • 在某些情况下,您需要这样的速度,因为您需要在缓冲区耗尽之前释放一些底层 C++ 内存。让我读到这个问题的确切案例。
    【解决方案3】:

    del 语句不回收内存。它删除了一个引用,这会减少该值的引用计数。如果计数为零,则可以回收内存。 CPython 会立即回收内存,无需等待垃圾收集器运行。

    实际上,垃圾收集器只需要回收循环结构。

    正如 Waleed Khan 在他的评论中所说,Python 内存管理可以正常工作,您不必担心。

    【讨论】:

    • 我认为 CPython 永远不会将内存释放回操作系统,即使它已被回收。
    • 我不知道该怎么说:“CPython 会立即回收内存,无需等待垃圾收集器运行。”
    • 该评论与我今天在 SO 周围看到的很多内容相矛盾,但是将大型数据库表作为副本读入内存,然后 del reference 导致内存被释放,因此垃圾收集被调用,并且(尽管对此没有时间保证)解释器正在将该内存返回给系统。如果我改为读取我的表并且不将其分配给变量,那么它就是一个孤岛,我必须显式调用 gc.collect() 才能找到它并释放它。
    • @pvlkmrv 这听起来不对:如果您不将表分配给变量,那么引用计数将为零,并且将被回收。岛屿不是问题,它是需要 gc 通行证才能回收的循环引用。
    • del x 对垃圾回收的作用与x = None 没有什么不同。它只是从 x 的值中删除一个引用。
    【解决方案4】:

    “删除名称会从本地或全局名称空间中删除该名称的绑定”。不多也不少。它对 name 指向的对象没有任何作用,除了减少其 refcount,如果 refcount 不为零,即使 GC 运行,也不会收集该对象。

    【讨论】:

      猜你喜欢
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 2021-08-10
      • 2014-09-05
      • 2011-05-30
      • 2018-08-22
      • 2018-06-16
      • 2011-08-02
      相关资源
      最近更新 更多