从RAM中删除变量

2024-04-25 16:56:01 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面显示的函数中,我想在使用x之后从内存中清除它的值。你知道吗

def f(x, *args):
   # do something
   y = g(x) # here i want to use x as argument and clear value of x from ram
   # do something

我尝试了以下方法并使用memory_profiler检查了内存使用情况,但没有任何效果:

  • del x
  • ^{}

我尝试的示例代码:

%%file temp.py
import lorem

@profile
def f(x, use_none=True):
  # do something
  y = g(x)
  if use_none:
    x = None
  else:
    del x
  # do something


def g(x):
  n = len(x)
  return [lorem.paragraph() * i for i in range(n)]

if __name__ == '__main__':
  x = g([1] * 1000)
  # f(x, True)
  f(x, False)

memory_profiler命令:

python -m memory_profiler temp.py

结果(使用None):

Filename: temp.py

Line #    Mem usage    Increment   Line Contents
================================================
     3  187.387 MiB  187.387 MiB   @profile
     4                             def f(x, use_none=True):
     5                               # do something
     6  340.527 MiB  153.141 MiB     y = g(x)
     7  340.527 MiB    0.000 MiB     if use_none:
     8  340.527 MiB    0.000 MiB       x = None
     9                               else:
    10                                 del x

结果(使用del):

Filename: temp.py

Line #    Mem usage    Increment   Line Contents
================================================
     3  186.723 MiB  186.723 MiB   @profile
     4                             def f(x, use_none=True):
     5                               # do something
     6  338.832 MiB  152.109 MiB     y = g(x)
     7  338.832 MiB    0.000 MiB     if use_none:
     8                                 x = None
     9                               else:
    10  338.832 MiB    0.000 MiB       del x

编辑 从全局和全局删除gc.收集()不工作

Filename: temp.py

Line #    Mem usage    Increment   Line Contents
================================================
     4  188.953 MiB  188.953 MiB   @profile
     5                             def f(x, use_none=True):
     6                               # do something
     7  342.352 MiB  153.398 MiB     y = g(x)
     8  342.352 MiB    0.000 MiB     if use_none:
     9                                 x = None
    10                                 globals()['x'] = None
    11                                 gc.collect()
    12                               else:
    13  342.352 MiB    0.000 MiB       del x
    14  342.352 MiB    0.000 MiB       del globals()['x']
    15  342.352 MiB    0.000 MiB       gc.collect()

另外,我写这段代码只是为了参考, 在我的实际代码中,我多次从一个函数调用另一个函数,有时根据某个参数值和某个操作后的x值从内部调用同一个函数。你知道吗

每次调用后,我都想在某个操作后删除x。你知道吗


Tags: pynonetrueifusedeflineprofile
2条回答

假设您使用的是CPython(也可能是其他实现),则当对象的引用计数降至零时,会触发垃圾回收。即使对象没有立即被垃圾收集,这也不是您看到结果的原因。原因是您不能垃圾收集仍然具有强引用的对象。你知道吗

del解除当前命名空间中名称的绑定,将引用计数减少1。它实际上并没有删除任何内容。del=相反,而不是__new__。你知道吗

None或任何其他对象赋给名称也会减少原始绑定的引用计数。唯一的区别是重新分配会将名称保留在命名空间中。你知道吗

x = g([1] * 1000)在全局模块名称空间中创建一个对象。然后调用f,并将该对象绑定到f的本地命名空间中的名称x。此时,有两个对它的引用:一个在本地名称空间中,另一个在全局名称空间中。你知道吗

在卸载模块之前,在正常情况下对象不会消失。您也可以在f中尝试以下操作:

del x
del globals()['x']

另一种方法是使用临时变量来避免在全局命名空间中赋值:

f(g([1] * 1000), False)

传递给f的临时变量将在f返回时立即消失,即使没有del,因为它没有在其他地方引用。你知道吗

这两个选项都可能需要在之后调用gc.collect(),但在CPython中不应该这样。你知道吗

Python垃圾回收将在一段时间后自动释放未使用的内存。如果要立即执行gc,可以在del之后尝试以下操作。你知道吗

import gc
gc.collect()

相关问题 更多 >