您可以看到该错误(第一个,从 2007 年开始)已被 nnorwitz 关闭为“wontfix”,并且他的帖子在错误报告中。
你为什么Py_Initialize/Py_Finalize
不止一次打电话?为什么不做这样的事情(为了方便起见,我有点混合 C 和 Python):
/* startup */
Py_Initialize();
/* do whatever */
while (moreFiles()) {
PyRun_SimpleString("execfile('%s')" % nextFile());
/* do whatever */
}
/* shutdown */
Py_Finalize();
问题是大多数编写 Python 模块的人并不担心如果他们的模块被最终确定和重新初始化会发生什么,并且通常不关心在最终确定期间进行清理。模块作者知道当进程退出时所有的内存都会被释放,除此之外什么都不用操心。
所以这不是一个真正的错误,它实际上是一千个错误——每个扩展模块一个。对于影响少数用户的错误来说,这是一项巨大的工作,其中大多数用户都有可行的解决方法。
您总是可以省略对 的调用Py_Finalize
,第二次调用Py_Initialize
是无操作的。这意味着当您第一次运行 Python 脚本时,您的应用程序将使用额外的内存,并且在您退出之前,额外的内存不会返回给操作系统。只要您仍然偶尔运行 Python 脚本,我就不会将其归类为泄漏。你的应用程序可能不是 Valgrind-clean,但它比像筛子一样泄漏要好。
如果您需要卸载(纯)Python 模块以避免内存泄漏,您可以这样做。只需将它们从sys.modules
.
缺点Py_Finalize
:如果你在重复执行 Python 脚本,那么在它们之间运行没有多大意义Py_Finalize
。每次重新初始化时都必须重新加载所有模块;我的 Python 在启动时加载了 28 个模块。
附加评论:该错误不仅限于 Python。如果您尝试卸载和重新加载库,任何语言的大量库代码都会泄漏内存。许多库调用 C 代码,许多 C 程序员假设他们的库被加载一次,并在进程退出时卸载。