0

我有以下情况:

我正在使用第三方 .net 库,它调用非托管代码来做它需要的事情(.net 的东西只是一个瘦包装器)。该库具有各种 IDisposable 实现等,我将其包装在 usings 中,但它仍然像我想的那样泄漏内存,错误,筛子(我已经能够在单元测试中最终证明这一点)。

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

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

显然,这一切都很棘手(命令行参数解析、序列化等都增加了复杂性并减慢了速度)但它的优点是它非常简单并且可以工作(谢天谢地,您甚至可以使用 CreateNoWindow 关闭窗口,这样用户应用程序也没有注意到任何不愉快的事情)。

我想到的其他方法:

  • 卸载应用程序池等等,但由于泄漏的内存是在.net 之外分配的,我认为这可能无济于事,还是会这样?
  • 我还考虑过尝试卸载 DLL,但它看起来有点危险——我可以安全可靠地执行此操作吗?

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

有没有办法让我保持一切都在进行中,并以某种方式清理这个第三方库的底部,这样我就不会泄漏内存?

4

1 回答 1

1

...我想它仍然像一个错误的筛子一样泄漏内存(我已经能够在单元测试中最终证明这一点)。

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

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

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

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

卸载应用程序池等等,但由于泄漏的内存是在.net 之外分配的,我认为这可能无济于事,还是会这样?

正确 - 这无济于事。

我还考虑过尝试卸载 DLL,但它看起来有点危险——我可以安全可靠地执行此操作吗?

那很可能解决不了问题。如果代码如您所说的那样有问题,那么在卸载时清理分配的资源很可能不会很好。(而且系统也不会为它清理它的资源——如果它分配了一个资源而不释放它,那么该资源将有效地泄漏。)

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

于 2012-07-09T09:09:22.590 回答