为什么CPython退出时并不释放所有的内存
CPython是Python的默认和最广泛使用的解释器或实现。它是原始的Python版本,能够理解使用Python规范编写的代码。
Python注重在退出时清理内存,并尝试销毁每个对象,但不幸的是,当Python退出时,不总是释放全局命名空间中引用的对象。原因是循环引用。此外,C库分配的某些内存是无法释放的。可以使用atexit模块强制Python在释放时删除某些内容。
atexit模块
如果要强制Python在释放时删除某些内容,请使用atexit模块。atexit模块定义了函数来注册和取消注册清理函数。注册的函数将在正常解释器终止时自动执行。atexit按照注册的相反顺序运行这些函数;如果你注册了P、Q和R,它们将按照R、Q、P的顺序在解释器终止时运行。
让我们看看如何在Python中安装atexit模块:
pip install atexit
导入atexit −
import atexit
atexit模块的方法
下面是方法:
- atexit.register(func, *args, **kwargs) - 注册func作为在程序结束时执行的函数。任何要传递给func的可选参数都必须作为参数传递给register()。
-
atexit.unregister(func) - 从要在解释器关闭时运行的函数列表中删除func。如果func之前没有被注册过,则unregister()不会有任何操作。如果func被注册了多次,则atexit调用堆栈中每次出现的该函数都将被删除。
示例
让我们看一个示例:
try:
with open('counterfile') as infile:
_count = int(infile.read())
except FileNotFoundError:
_count = 0
def incrcounter(n):
global _count
_count = _count + n
def savecounter():
with open('counterfile', 'w') as outfile:
outfile.write('%d' % _count)
import atexit
atexit.register(savecounter)
以上示例演示了模块在被导入时如何从文件中初始化计数器,并在程序终止时自动保存计数器的更新值,而无需依赖应用程序在终止时明确调用该模块。