5

此错误报告指出,截至 2007 年 6 月,Python 解释器在具有嵌入式 Python 解释器的 C/C++ 应用程序中调用 Py_Finalize 后不会清理所有分配的内存。建议在应用程序终止时调用 Py_Finalize 一次。

此错误报告指出,截至 3.3 版和 2011 年 3 月,解释器仍然泄漏内存。

有谁知道这个问题的当前状态?我很担心,因为我有一个应用程序,在该应用程序中,每个运行实例都会多次调用解释器,并且我遇到了内存泄漏。

我已经在使用 boost::python 来处理引用计数,并且我清除了在两次运行之间运行 Python 程序创建的所有引用的全局字典。我有一些单身课程 - 这些可能是问题吗?

这是一个易于处理的问题还是 Python 解释器中的错误?

4

1 回答 1

6

您可以看到该错误(第一个,从 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 程序员假设他们的库被加载一次,并在进程退出时卸载。

于 2012-01-10T05:44:53.590 回答