6

我需要使用无法修改的外部程序集。假设我使用该程序集中的一个类,如下所示:

using (ExternalWidget widget = new ExternalWidget())
{
    widget.DoSomething();
}

每次我调用此代码时,它都会泄漏非托管内存。ExternalWidget实现IDisposable,我已经将它包装在一个using语句中,但ExternalWidget没有清理它的非托管资源。

由于我无权访问ExternalWidget代码,因此我无法以正确的方式解决此问题。有没有其他方法可以释放所使用的内存资源ExternalWidget

4

1 回答 1

4

如果这是一个真正的非托管内存泄漏并且您无法更改代码,那么您几乎无能为力。框架无法接受这一点,也无法清理该代码。

在这种情况下,方法是隔离该组件。这意味着访问它会有很多开销,但您无能为力。

您不能在另一个应用程序域中运行代码,因为非托管代码没有应用程序域的概念。

这留下了过程级别。我建议在 WCF 中创建一个服务合同,模仿对方法的ExternalWidget调用Shutdown

然后,您将创建一个 EXE,它将通过命名管道绑定公开此合同(使用会话,因此您可以保留ExternalWidget实例,除非每个调用都是无状态的)。

作为 EXE 的参数,它将采用唯一标识符(使用 a Guid)并将其用作为 WCF 服务设置端点的一部分。

然后,您将拨打电话,当您完成该实例时ExternalWidget,请拨打Shutdown; EXE 会知道停止等待,然后进程将退出,操作系统将回收内存。

当然,这里有大量的开销,所以如果你发现你正在进行很多调用并且不需要为每组调用创建一个新进程,你可以将这个想法扩展为一个计算调用的服务并然后在需要时回收该进程(服务仍然需要掏空,否则耗尽资源)。

请注意,如果这是托管内存问题,那么您始终可以启动一个新的应用程序域,在那里运行您的代码(根据需要来回编组结果),然后释放应用程序域。

于 2012-10-25T14:18:52.113 回答