我需要使用无法修改的外部程序集。假设我使用该程序集中的类,如下所示:
using (ExternalWidget widget = new ExternalWidget())
{
widget.DoSomething();
}
每次调用此代码时,都会泄漏非托管内存。 ExternalWidget
实现IDisposable
并将其包装在using
语句中,但ExternalWidget
不会清除其非托管资源。
由于我无法访问ExternalWidget
代码,因此我无法以正确的方式解决此问题。有没有其他方法可以释放ExternalWidget
使用的内存资源?
答案 0 :(得分:4)
如果它是真正的非托管内存泄漏并且您无法更改代码,那么您无能为力。框架无法接受,也无法清理该代码。
在这种情况下的方法是隔离该组件。这意味着访问它会有很多开销,但是你无能为力。
您无法在其他应用程序域中运行代码,因为非托管代码没有应用程序域的概念。
这留下了流程级别。我建议在WCF中创建一个服务合同,模仿ExternalWidget
和Shutdown
方法的调用。
然后,您将创建一个EXE,它将公开此合同(使用会话,因此您可以通过命名管道绑定保留ExternalWidget
实例,除非每个调用都是无状态的。)
作为EXE的参数,它将采用唯一标识符(使用Guid
)并将其用作为WCF服务设置端点的一部分。
然后,您将拨打电话,当您完成ExternalWidget
的该实例后,请致电Shutdown
; EXE会知道停止等待然后进程退出,操作系统将回收内存。
当然,这里有很多巨额的开销,所以如果你发现你正在进行大量的通话而且每个通话都不需要新的进程,你可以扩展这个想法变成了一个服务,它计算了调用,然后在需要的时候重新开始流程(服务仍然需要外包,或它将耗尽资源)。
请注意,如果这是托管内存问题,那么您可以随时启动新的应用程序域,在那里运行代码(根据需要来回封送结果)然后发布应用程序域。