【问题标题】:Is it possible for a Python function to still use memory after being called?Python函数在被调用后是否仍然可以使用内存?
【发布时间】:2017-11-08 01:08:47
【问题描述】:

如果我在 Python 3 (func()) 中运行一个函数,是否有可能在 func() 内部创建但在完成后无法访问的对象会导致其内存使用量增加?

例如,将运行

def func():
    # Objects being created, that are not able to be used after function call has ended.

while True:
    func()

无论func()中的内容是否导致程序内存不足?

如果程序持续使用内存,func() 中可能发生的哪些事情会导致它在被调用后继续使用内存?

编辑: 我只是询问创建函数结束后无法再访问的对象,因此应该删除它们。

【问题讨论】:

  • 简短的回答是肯定的 - non_local_list.append(1) 将是一个微不足道的例子。
  • 你能解释一下为什么你想要这样的行为吗?也许这个网站超出范围...
  • 另一个简单的例子:def f():''; f.__doc__ += ' '
  • 在这种情况下,您需要向我们展示表现出这种行为的minimal reproducible example。我们无法调试无法运行甚至无法查看的代码。
  • 是的,我很感激这一点,我正在创建一个,但我只是想先检查一下是否有可能出现问题(我不只是发疯了!)

标签: python python-3.x memory memory-management memory-leaks


【解决方案1】:

是的,Python 函数在执行完之后仍然可能使用内存 调用。

  • Python 使用垃圾回收 (GC) 进行内存管理。大多数GC(我想 可能有一些例外)不保证它们是否或何时释放 未引用对象的内存。假设你有一个函数 consume_lots_of_memory() 并称之为:

    while True:
        consume_lots_of_memory()
    

    无法保证在第一次调用中分配的所有内存 到consume_lots_of_memory() 将在它被调用之前被释放 第二次。理想情况下,GC 会在调用完成后运行,但它 可能会在第五次通话中运行到一半。所以要看GC的时候 运行,您最终可能会消耗比预期更多的内存,并且 甚至可能内存不足。

  • 您的函数可能正在修改全局状态,并使用大量 永远不会被释放的内存。假设您有一个模块级缓存和一个 函数cache_lots_of_objects() 调用为:

    module_cache = {}
    while True:
        cache_lots_of_objects()
    

    每次调用cache_lots_of_objects() 只会添加到缓存中,并且 缓存只是不断消耗更多的内存。即使GC及时 释放在cache_lots_of_objects() 中创建的非缓存对象,您的 缓存最终可能会消耗掉你所有的内存。

  • 您可能会遇到来自 Python 本身的实际内存泄漏(不太可能 但可能),或从第三方库不正确地使用 C API,使用 泄漏的 C 库,或与 C 库的错误接口。

  • 关于内存使用的最后一点说明。仅仅因为 Python 释放了已分配的 对象,并不一定意味着会从进程中释放内存 并返回操作系统。原因与记忆的方式有关 以块(页)的形式分配给进程。见 abarnert 的answerReleasing memory in Python 以获得比我能提供的更好的解释。

【讨论】:

  • 谢谢!这真的很有用。尤其是第一点和最后一点。我说我可以使用gc.collect() 强制GC 收集是否正确?
  • @Gloin 是的,没错。在生成大型导出时,我不得不自己使用一次。
猜你喜欢
  • 1970-01-01
  • 2019-11-19
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 2010-10-08
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多