在调用Python函数后,不会释放RAM

2024-09-27 17:58:27 发布

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

我正在使用一个内部Python库进行科学计算。我需要连续复制一个对象,修改它,然后删除它。对象是巨大的,这会导致我的机器在几个周期后耗尽内存。你知道吗

第一个问题是我使用python的del来删除对象,这显然只是取消了对象的引用,而不是释放RAM。你知道吗

第二个问题是,即使我将整个过程封装在一个函数中,在调用函数之后,RAM仍然没有释放出来。下面的代码片段可以更好地解释这个问题。你知道吗

ws = op.core.Workspace()
net = op.network.Cubic(shape=[100,100,100], spacing=1e-6)
proj = net.project

def f():
    for i in range(5):
        clone = ws.copy_project(proj)
        result = do_something_with(clone)
        del clone

f()
gc.collect()

>>> ws
{'sim_01': [<openpnm.network.Cubic object at 0x7fed1c417780>],
 'sim_02': [<openpnm.network.Cubic object at 0x7fed1c417888>],
 'sim_03': [<openpnm.network.Cubic object at 0x7fed1c417938>],
 'sim_04': [<openpnm.network.Cubic object at 0x7fed1c417990>],
 'sim_05': [<openpnm.network.Cubic object at 0x7fed1c4179e8>],
 'sim_06': [<openpnm.network.Cubic object at 0x7fed1c417a40>]}

我的问题是如何完全删除Python对象?你知道吗

谢谢!你知道吗

另外,在代码片段中,每次调用ws.copy_project时,proj的副本都存储在ws字典中。你知道吗


Tags: 对象代码projectwsobjectclonesimnetwork
1条回答
网友
1楼 · 发布于 2024-09-27 17:58:27

这里有一些非常聪明的Python人。他们也许能告诉你保持内存清晰的更好方法,但我以前使用过有漏洞的库,并且找到了一种(到目前为止)万无一失的方法来保证内存在使用后被清除:在另一个进程中执行内存猪。你知道吗

要做到这一点,您需要安排一种简单的方法,使您的长期计算可以单独执行。为此,我在现有的python脚本中添加了特殊标志,告诉它只运行该函数;您可能会发现将该函数放在一个单独的.py文件中更容易,例如:

做点什么_带.py

import sys
def do_something_with(i)
    # Your example is still too vague.  Clearly, something differentiates
    # each do_something_with, otherwise you're just taking the
    # same inputs 5 times over.
    # Whatever the difference is, pass it in as an argument to the function

    ws = op.core.Workspace()
    net = op.network.Cubic(shape=[100,100,100], spacing=1e-6)
    proj = net.project

    # You may not even need to clone anymore?
    clone = ws.copy_project(proj)
    result = do_something_with(clone)

# Whatever arg(s) you need to get to the function, just pass it in on the command line
if __name__ == "__main__":
    sys.exit(do_something_with(sys.args[1:]))

您可以使用任何处理子流程的python工具来实现这一点。在python3.5+中,建议使用subprocess.run。你可以把你的大功能改成这样:

import subprocess

invoke_do_something(i):
    completed_args = subprocess.run(["python", "do_something_with.py", str(i)], check=False)
    return completed_args.returncode

results = map(invoke_do_something, range(5))

很明显,您需要根据自己的情况对其进行调整,但是通过在子进程中运行,可以保证您不必担心内存被清理。作为额外的奖励,你可以使用多进程池映射一次使用多个处理器。(我特意将其编码为使用map来简化这种转换。如果您愿意,您仍然可以使用for循环,然后您就不需要invoke...函数了。)多处理可以加快处理速度,但是由于您已经担心内存问题,这几乎肯定是个坏主意-对于大内存猪的多个进程,系统本身很可能会很快耗尽内存并终止进程。你知道吗

你的例子相当模糊,所以我写了一个很高的层次。如果你需要的话,我可以回答一些问题。你知道吗

相关问题 更多 >

    热门问题