gpt4 book ai didi

python - 从 RAM 中删除变量

转载 作者:太空狗 更新时间:2023-10-30 00:52:43 24 4
gpt4 key购买 nike

在下面显示的函数中,我想在使用后从内存中清除 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
  • 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.collect() 中删除不起作用

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。

最佳答案

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

del 取消绑定(bind)当前 namespace 中的名称,将引用计数减一。它实际上并没有删除任何东西。 del= 的逆运算,而不是 __new__

None 或任何其他对象分配给该名称也会减少原始绑定(bind)的引用计数。唯一的区别是重新分配将名称保留在 namespace 中。

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

您的对象在正常情况下不会消失,直到您的模块被卸载。您还可以在 f 中尝试类似以下内容:

del x
del globals()['x']

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

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

您传递给 f 的临时变量将在 f 返回后立即消失,即使没有 del,因为它没有在其他地方被引用.

任何一个选项都可能需要在之后调用 gc.collect(),但在 CPython 中不应该。

关于python - 从 RAM 中删除变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56574567/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com