如何处理.net泄漏的第三方库?

时间:2012-07-09 08:53:52

标签: .net pinvoke

我有以下情况:

我正在使用第三方.net库调用非托管代码来执行它所需要的东西(.net东西只是一个薄的包装器)。该库有各种IDisposable实现等我正在使用它包装但它仍然泄漏记忆像我,错误,筛子我想(我已经能够在单元测试中最终证明这一点)。

理想情况下,当然我会让第三方修理他们的图书馆,但他们没有回应,我很遗憾,也不能放弃它,所以我现在正在做的就是这个......

我正在使用这个第三方库进行的工作可以非常容易地封装,所以在我需要的地方我启动一个带有几个命令行参数的进程并捕获标准输出。该过程完成了它需要做的事情,并通过简单地将其序列化为标准输出来返回结果对象,然后启动应用程序中启动该过程的方法反序列化结果对象并返回它,就像没有发生任何怪异一样。

显然这一切都很糟糕(命令行参数解析,序列化等都会增加复杂性并减慢速度)但它的优势在于它非常简单并且可以正常工作(谢天谢地你甚至可以用CreateNoWindow关闭窗口,所以应用程序的用户也没有注意到任何不幸的事情。

我想到的其他方法:

  • 卸载应用程序池以及诸如此类但由于泄漏的内存是在.net之外分配的,我认为这可能没有用,或者不会吗?
  • 我还试图卸载DLL,但它看起来有点危险 - 我能安全可靠吗?

所以,我的问题基本上归结为......

有没有办法让我可以保留所有进程并以某种方式清理第三方库的底部,以便我不泄漏内存?

1 个答案:

答案 0 :(得分:1)

  

......我想它仍然会像记忆,错误,筛子那样泄漏(我已经能够在单元测试中证明这一点)。

我假设答案是'不',但我不得不问 - 它是否有可能“泄漏”记忆 在正常使用期间,但是当你“关闭”时,它是否足够聪明以便清理它?我至少遇到过几个库,它们的内部缓存似乎以无限制的方式增长,但是在调用库的终止例程时会被清理。

假设泄漏真的只是错误,那么......

  

...我需要它的地方我使用几个命令行参数启动一个进程并捕获标准输出

......考虑到情况的参数,我认为你的方法是最合理的。实际上,您正在托管您不“信任”的代码 - 可能不是出于安全原因,而是出于性能/可靠性原因。

  

卸载应用程序池以及诸如此类但由于泄漏的内存是在.net之外分配的,我认为这可能没有用,或者不会吗?

正确 - 这无济于事。

  

我还考虑过试图卸载DLL,但它看起来有点危险 - 我能安全可靠吗?

最有可能无法解决问题。如果代码像你说的那样错误,那么在卸载时清理已分配的资源很可能不会很好。 (并且系统不会为它清理资源 - 如果它在没有释放资源的情况下分配资源,那么该资源将会有效泄漏。)

在这种情况下,你真的没有什么可以做的。我能想到的唯一最后的选择是尝试挂钩/拦截第三方库的例程,以某种方式将其所有分配强制到一个池中,您可以一次释放所有(在释放库之后)。 但你真的不应该尝试这样做。这很危险,几乎肯定不值得努力,太难以正确实施等等。