【问题标题】:Code block in python in order to free memorypython中的代码块以释放内存
【发布时间】:2022-02-03 05:43:54
【问题描述】:

很简单的问题:
我有一些代码来显示一些图表,它为图表准备数据,我不想浪费内存(有限)......有没有办法拥有一个“本地范围”,所以当我们到最后,里面的东西都被释放了吗?

我来自 C++,你可以在 { ... } 中定义代码,所以最后一切都被释放了,你不必关心任何事情

在 python 中有类似的东西吗?

我唯一能想到的是:

def tmp():
   ... code ...

tmp()

但是很丑,而且我肯定不想在最后列出所有del x

【问题讨论】:

  • Python 的作用域规则不像 C 那样复杂。函数作用域,正如你所拥有的那样,是正确的方法。
  • @TimRoberts 是的,我可以看到,但是我在 python 方面的经验比在 C++ 方面要少,所以我问是因为我可能不知道一些技巧

标签: python memory scopes


【解决方案1】:

在 Python 中处理释放内存的机制称为“垃圾收集器”,这意味着没有理由在绝大多数 Python 代码中使用 del

在 Python 中编程时,您“不应该”关心诸如为变量分配和释放内存之类的低级事情。

话虽如此,将您的代码放入函数中(尽管最好称为比tmp() 更清晰的东西)绝对是一个好主意,因为它会使您的代码更具可读性和“Pythonic”

【讨论】:

    【解决方案2】:

    来自 C++ 并且已经偶然发现了 python 的主要区别(缺点)之一,这是内存管理。Python 垃圾收集器将删除所有超出范围的对象。释放对象的内存虽然不能保证此内存将实际返回给系统,但即使没有使用,python 程序也会保留相当大的一部分。如果您遇到内存问题并且想要将内存释放回系统,唯一安全的方法是将内存密集型函数运行到一个单独的进程中。python中的每个进程都有自己的解释器,该进程消耗的任何内存都会在进程退出时返回系统。

    【讨论】:

    • 我不是在问垃圾收集器是如何工作的,而是如果有更多“清晰”的方法可以做到这一点......顺便说一句,tnk u
    • 我认为没有更优雅的方法,除了分叉一个可能很昂贵的单独进程
    【解决方案3】:

    如果有任何东西包含对您的对象的引用,则它不能被释放。默认情况下,全局范围内的任何内容都将保存在全局命名空间 (globals()) 中,据解释器所知,源代码的下一行可以引用它(或,另一个模块可以从当前模块导入它),因此永远不能隐式释放全局变量。

    这迫使您要么显式删除对具有del 的对象的引用,要么将它们置于函数的本地范围内。这可能看起来很难看,但是如果您遵循函数应该做好一件事和做好一件事的理念(感谢 Unix!),您已经将代码分段为函数。在一次性异常情况下,您在函数的早期分配了大量内存,并且在中途不再需要它,您可以del 对其的引用。

    我知道这不是您想听到的答案,而是 Python 的现实。您可以通过在内部嵌套函数 defs 或 classs 来完成类似的事情,但这有点 hacky(或者在 class 的情况下,不需要调用/实例化,非常 hacky)。

    我还要提到,有一个gc 内置模块用于与垃圾收集器进行交互。在这里,您可以立即触发垃圾回收(否则 python 最终会收集您 del 引用的内容),以及检查给定对象有多少引用。

    如果您对分配发生的位置感到好奇,您还可以使用内置的tracemalloc 模块来跟踪所述分配。

    【讨论】:

    • “如果有任何东西包含对您的对象的引用,它就不能被释放。” - 除非例如这是唯一的引用,并且您的对象拥有对该任何东西的唯一引用。
    • @KellyBundy 这是一个公平的观点 - Python 的垃圾收集足够聪明,可以处理循环引用,所以我想我在那里过度概括了。
    • 我不是在问垃圾收集器是如何工作的,而是如果有更多“清晰”的方法可以做到这一点......顺便说一句,你
    猜你喜欢
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多