我正在使用Python的ctypes模块通过加载供应商的库来使用与业务软件相关的C API。但是,在部署我编写的软件后,我发现供应商的库会根据其API中某个特定函数的调用次数而持续和可预测地泄漏内存。即使我在不使用堆分配的C程序中复制了这个泄漏问题。我联系了供应商关于这个问题,他们回答说正在解决,但我可能无法真正期望在下一个软件版本之前修复它。我想过当泄漏函数的调用次数达到一定阈值时重新加载供应商的dll,但这并没有释放泄漏的内存。我发现可以通过以下方式强制卸载该库:
这会释放内存,但使用供应商的API一段时间后,解释器似乎会随机崩溃。
我在Python错误跟踪器中找到了描述我的情况的问题: https://bugs.python.org/issue14597 如果仍有对库的引用,强制卸载它将不可避免地导致Python解释器崩溃。
最坏的情况是,我考虑在单独的进程中加载供应商的库,使用多处理队列代理请求,并设置看门狗以在解释器死亡时重新创建进程。
是否有更好的方法来解决这个问题?
_ctypes.FreeLibrary(vendor_dll._handle)
这会释放内存,但使用供应商的API一段时间后,解释器似乎会随机崩溃。
我在Python错误跟踪器中找到了描述我的情况的问题: https://bugs.python.org/issue14597 如果仍有对库的引用,强制卸载它将不可避免地导致Python解释器崩溃。
最坏的情况是,我考虑在单独的进程中加载供应商的库,使用多处理队列代理请求,并设置看门狗以在解释器死亡时重新创建进程。
是否有更好的方法来解决这个问题?
DLL_PROCESS_DETACH
上释放它们。至于卸载vendor_dll
,您应该首先删除所有对当前实例的引用,并确保没有任何东西再次执行其代码,包括未完成的异步回调。然后您可以卸载和重新加载DLL。共享库是引用计数的,因此为了确保它实际上已被卸载,请调用FreeLibrary
直到它引发一个OSError
。 - Eryk Sun