![]() |
Embedded Python Memory Leaks - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Embedded Python Memory Leaks (/thread-38205.html) |
Embedded Python Memory Leaks - Alexei - Sep-15-2022 Hi dear Python team, I am a building a c/c++ application for general purpose and I would like to have in the application the possibility of running “Python” scripting code. Python has proved to be a good programming language to deal with heavy Math as in AI. Now when I embed Python in my application things go perfect, except for memory leaks! As a sample, by just issuing the following code leaves memory leaks of around (2Mb): #define PY_SSIZE_T_CLEAN #define Py_LIMITED_API 0x03000000 #include <Python.h> #pragma comment (lib,"python3.lib") int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { Py_InitializeEx(0); //For Embeded Python Py_FinalizeEx(); ..More code.. return 0; }Is there something I must do to cause Python to release all resources allocated thanks RE: Embedded Python Memory Leaks - Alexei - Sep-16-2022 Thanks for your replay Larz60, sorry I am new to this forum and I am learning how to do stuff: The code I use is as simple as I just wrote "..mode code.." at this point is empty, since I am testing python engine before I add it to the project where I plan to use it. As you can see even the python dll gets unloaded when I finished with Python since I do late binding to python dlls due to the fact that the application might not use python for some applications while might use it for others and I don't want the user having to install python if it does not plan to use python scripting. I would like to know what does Py_InitializeEx(0); do that .Py_FinalizeEx(); cannot undo regarding computer resource utilization. I am working with VS2019 generation a windows application 64 bits. Thanks a log!!! VS2019 log fragment: The object constructor runs this function and print the message "0x1383630A630 -> Python Object created!...":# ///////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT PythonObject_Init(LPPYTHONOBJECTDATA pObjectData,LPEXCEPINFO pei) { HRESULT hr = S_OK; //first time Pythoon is called if (!hPythonDll) { if ((hr = PythonObject_BindFunctions(pObjectData, pei)) != S_OK) return hr; } if (hPythonDll && !pObjectData->bEngineInitialized) { callPython.Py_InitializeEx(0); //For Embeded Python if (callPython.Py_IsInitialized()) { pObjectData->bEngineInitialized = TRUE; callPython.PyGC_Enable(); dwPyObjCounter++; } else hr = PythonObject_RiseException(pObjectData, pei); } return hr; } # ///////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT PythonObject_BindFunctions(LPPYTHONOBJECTDATA pObjectData, LPEXCEPINFO pei) { HRESULT hr = S_OK; if (pwcPyLibPathName) { hPythonDll = LoadLibrary(pwcPyLibPathName); if (hPythonDll) { char* pchar = "Py_InitializeEx"; //Bind Functions I use callPython.Py_InitializeEx = (f_Py_InitializeEx) GetProcAddress(hPythonDll, pchar); if (!callPython.Py_InitializeEx) goto PythonBindError; pchar = "Py_IsInitialized"; callPython.Py_IsInitialized = (f_Py_IsInitialized)GetProcAddress(hPythonDll, pchar); if (!callPython.Py_IsInitialized) goto PythonBindError; pchar = "Py_FinalizeEx"; callPython.Py_FinalizeEx = (f_Py_FinalizeEx) GetProcAddress(hPythonDll, pchar); if (!callPython.Py_FinalizeEx) goto PythonBindError; goto PyBindOk; PythonBindError: { wchar_t *pwcFunction = WStrFromChar(pchar); wchar_t* pwcDummy = NULL; pwcDummy = WStrConcatenate(pwcFunction, ALEXPYTHONOBJECT_ERROR_UNSSUPORTEDVERSION_STR); if (pwcDummy) { CreateErrorInfo2(pei, SysAllocString(pwcDummy), NULL, NULL, 0, (ALEXPYTHONOBJECT_ERROR_UNSSUPORTEDVERSION), HRESULT_CODE(ALEXPYTHONOBJECT_ERROR_UNSSUPORTEDVERSION)); }else CreateErrorInfo2(pei, SysAllocString(ALEXPYTHONOBJECT_ERROR_UNSSUPORTEDVERSION_STR), NULL, NULL, 0, (ALEXPYTHONOBJECT_ERROR_UNSSUPORTEDVERSION), HRESULT_CODE(ALEXPYTHONOBJECT_ERROR_UNSSUPORTEDVERSION)); return DISP_E_EXCEPTION; } PyBindOk: hr = hr; } else { hr = GetLastError(); } } else hr = E_INVALIDARG; return hr; }while the object destructor calls the following function and print the message "0x1383630A630 -> Python Object Destroyed!...": VOID PythonObject_CleanUp(LPPYTHONOBJECTDATA pObjectData) { HRESULT hr = S_OK; # //==============TESTING this code!!!================ if (pObjectData->bEngineInitialized) { if (pObjectData->pPyMainModule) { callPython.Py_DecRef(pObjectData->pPyMainModule); pObjectData->pPyMainModule = NULL; } callPython.PyGC_Collect(); dwPyObjCounter--; if (dwPyObjCounter == 0) { callPython.Py_FinalizeEx(); pObjectData->bEngineInitialized = FALSE; if (FreeLibrary(hPythonDll)) { if (pwcPyLibPathName) CoTaskMemFree(pwcPyLibPathName); pwcPyLibPathName = NULL; hPythonDll = NULL; } } # //==============TESTING this code!!!================ } } |