下面是关于使用C++解释器的内存管理问题的简化版本。
下面的代码将正常运行,但随着时间的推移,其内存占用将逐渐增加。我添加了一行来手动调用Python垃圾收集;这并没有解决问题。
为了防止不断增长的内存泄漏,我需要对这些代码进行什么更改?
编辑:根据下面的建议,我进一步削减了pythonTest函数。它所做的就是创建一个环境,重新设置它,并关闭它。内存泄漏仍然存在。
我在Windows10上使用Python3.10.2。C++正在由Visual编译成C++14标准。我已经安装了OpenAI-Gym版本0.22.0。
void pythonTest(PyObject* inModule)
{
// Section 1: Get the make function:
PyObject* pMakeFunc = PyObject_GetAttrString(inModule, "make");
PyObject* pMakeArgs = PyTuple_New(1);
PyTuple_SetItem(pMakeArgs, 0, PyUnicode_FromString("LunarLanderContinuous-v2"));
// Section 2: Get the environment and its functions:
PyObject* pEnv = PyObject_CallObject(pMakeFunc, pMakeArgs);
PyObject* pEnvReset = PyObject_GetAttrString(pEnv, "reset");
PyObject* pEnvStep = PyObject_GetAttrString(pEnv, "step");
PyObject* pEnvClose = PyObject_GetAttrString(pEnv, "close");
PyObject* pEnvRender = PyObject_GetAttrString(pEnv, "render");
// Section 3: Reset the environment to get the initial observation:
PyObject* pInitialObsArray = PyObject_CallNoArgs(pEnvReset);
PyObject* pInitialObsListFunc = PyObject_GetAttrString(pInitialObsArray, "tolist");
PyObject* pInitialObsList = PyObject_CallNoArgs(pInitialObsListFunc);
// Clear section 3:
Py_CLEAR(pInitialObsList);
Py_CLEAR(pInitialObsListFunc);
Py_CLEAR(pInitialObsArray);
// Clear section 2: Close the environment, first:
PyObject_CallNoArgs(pEnvClose);
Py_CLEAR(pEnvRender);
Py_CLEAR(pEnvClose);
Py_CLEAR(pEnvStep);
Py_CLEAR(pEnvReset);
Py_CLEAR(pEnv);
// Clear section 1:
Py_CLEAR(pMakeArgs);
Py_CLEAR(pMakeFunc);
}
int main()
{
Py_Initialize();
// Get gym module:
PyObject* pGymName = PyUnicode_FromString("gym");
PyObject* pModule = PyImport_Import(pGymName);
// Get garbage collection module and collect function:
PyObject* pgcName = PyUnicode_FromString("gc");
PyObject* pgcModule = PyImport_Import(pgcName);
PyObject* pgcFunction = PyObject_GetAttrString(pgcModule, "collect");
for (int k = 0; k < 1000000; ++k)
{
pythonTest(pModule);
// Manually invoke the garbage collection:
PyObject* pGCReturn = PyObject_CallNoArgs(pgcFunction);
auto objectsCollected = PyLong_AsLong(pGCReturn);
std::cout << "Iteration " << k << " objects collected: "
<< objectsCollected << std::endl;
Py_CLEAR(pGCReturn);
}
Py_CLEAR(pgcFunction);
Py_CLEAR(pgcModule);
Py_CLEAR(pgcName);
Py_CLEAR(pModule);
Py_CLEAR(pGymName);
Py_Finalize();
return 0;
}
发布于 2022-03-16 18:44:13
问题既不是在Python中,也不是在它与C++的接口中。问题是在Box2D,这是使用的一些OpenAI健身房环境。
我可以重复上面的代码,同时创建一个不使用Box2D的不同环境(例如“Cartpol-v1”),让它在没有任何内存泄漏的情况下无休止地运行。一旦我将Box2D环境放回(如"BipedalWalker-v3“或"LunarLander-v2"),内存泄漏就会再次出现。
我可以在Python中完全重复上面的过程,并得到相同的结果。即使在每次破坏环境后手动运行垃圾回收,应用程序分配的内存也会无限增长。
任何环境上的重置功能都是它进行大量准备运行的地方,也是内存泄漏发生的地方。如果Box2D环境被无休止地创建和销毁,则不会出现内存泄漏。创建,重置,然后销毁?内存泄漏。
谢谢大家的帮助,但这是底层库中的一个bug。我得去那里递交。
发布于 2022-03-16 15:10:12
您每次在循环中创建一个新的pActionList,但是您似乎并没有处理它。
一般来说,虽然您已经将其描述为简化的代码版本,但它仍然相当复杂。我要说的是,继续把它去掉,直到问题解决为止。这应该能告诉你问题出在哪里。
https://stackoverflow.com/questions/71498764
复制相似问题