在下面显示的函数中,我想在使用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。你知道吗
假设您使用的是CPython(也可能是其他实现),则当对象的引用计数降至零时,会触发垃圾回收。即使对象没有立即被垃圾收集,这也不是您看到结果的原因。原因是您不能垃圾收集仍然具有强引用的对象。你知道吗
del
解除当前命名空间中名称的绑定,将引用计数减少1。它实际上并没有删除任何内容。del
与=
相反,而不是__new__
。你知道吗将
None
或任何其他对象赋给名称也会减少原始绑定的引用计数。唯一的区别是重新分配会将名称保留在命名空间中。你知道吗行
x = g([1] * 1000)
在全局模块名称空间中创建一个对象。然后调用f
,并将该对象绑定到f
的本地命名空间中的名称x
。此时,有两个对它的引用:一个在本地名称空间中,另一个在全局名称空间中。你知道吗在卸载模块之前,在正常情况下对象不会消失。您也可以在
f
中尝试以下操作:另一种方法是使用临时变量来避免在全局命名空间中赋值:
传递给
f
的临时变量将在f
返回时立即消失,即使没有del
,因为它没有在其他地方引用。你知道吗这两个选项都可能需要在之后调用
gc.collect()
,但在CPython中不应该这样。你知道吗Python垃圾回收将在一段时间后自动释放未使用的内存。如果要立即执行
gc
,可以在del
之后尝试以下操作。你知道吗相关问题 更多 >
编程相关推荐