3

相关问题:

如果一个import语句在函数内部,一旦函数退出,它占用的内存会被回收吗?如果是,那么回收的时间是确定性的(甚至是-ish)吗?

def func():
    import os
    ...
    # function about to exit; will memory occupied by `os` be freed?

如果有人知道关于micropython这个话题的行为,加分。

4

2 回答 2

3

第一次导入执行模块中的代码。它创建模块对象的属性。每个后续导入仅引用第一次导入创建的模块对象。

Python 中的模块对象实际上是单例。为此,Python 实现必须在第一次导入后保留唯一的模块实例,而不管模块绑定到的名称如何。如果它无论如何都绑定到一个名称,因为还有表单的导入from some_module import some_name

所以不,内存没有被回收。

不知道 Micropython,但如果它在这里大幅改变语义,我会感到惊讶。你可以简单地自己测试一下:

some_module.py:

value = 0

some_other_module.py:

def f():
    import some_module
    some_module.value += 1
    print(some_module.value)

f()
f()

这应该打印数字 1 和 2。

于 2017-10-18T17:22:21.327 回答
0

其次,@BlackJack 根据 Python 语义写的内容,“import”语句将模块引用添加到sys.modules,仅此一项就可以防止模块对象被垃圾收集。

您可以尝试这样做del sys.modules["some_module"],但不能保证模块占用的所有内存都会被回收。(这个问题之前出现过,但我不记得它的当前状态,例如字节码对象是否可以被垃圾收集)。

如果是,那么回收的时间是确定性的(甚至是-ish)吗?

在 MicroPython 中,“回收时间”肯定是不确定的,因为它使用纯粹的垃圾收集方案,没有引用计数。这意味着任何消耗资源的对象(文件、套接字)都应该显式关闭。

否则,函数级导入在 Python 中是有效且有用的习惯用法,在 MicroPython 中尤其有用。只有在命中特定的代码路径时,它才允许导入某些模块。例如,如果用户从不调用某个函数,则不会导入模块,从而为用户在此特定应用程序/调用中需要更多的任务节省更多内存。

于 2017-11-01T10:14:10.940 回答