为什么CPython退出时并非所有内存都被释放?


CPython是Python默认的、也是使用最广泛的解释器或实现。它是最初的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)

上面的例子演示了模块如何在导入时从文件中初始化计数器,并在程序终止时自动保存计数器的更新值,而无需依赖应用程序在终止时对此模块进行显式调用。

更新于:2022年9月19日

554 次浏览

开启您的职业生涯

通过完成课程获得认证

开始学习
广告
© . All rights reserved.