我必须调用一些写得不好的第三方COM组件,这些组件有内存泄漏,并且在长时间运行的过程中使用Single Threaded Apartment [STA]。
我知道单独的进程将是实现它的好方法,我可以偶尔从长时间运行的进程中重新启动它。
可以改用AppDomain吗?如果适当标记,AppDomain线程是否为STA线程?它是否有自己的COM对象内存?卸载AppDomain是否相当于杀死进程?
答案 0 :(得分:23)
AppDomain不提供与进程相同程度的隔离。事实上,如果您担心第三方组件状况不佳,则存在风险,它会占用您的.NET应用程序。
如果在卸载时执行非托管代码,则无法卸载AppDomain,因此您可能很难在AppDomain中控制第三方代码。见http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx
即使仅对托管代码,AppDomain也不提供强大的沙盒解决方案。例如。如果加载的代码产生任何线程,这些将在未处理的异常情况下取消整个过程。这个问题有更多信息:.NET - What's the best way to implement a "catch all exceptions handler"。
据我所知,在.NET应用程序中托管代码的最佳选择是实现自己的CLR主机进程,如IIS和SQL Server。
答案 1 :(得分:0)
AppDomain(应用程序域)是应用程序执行的隔离环境。
它们有助于提供隔离, 卸载和安全边界 执行托管代码。
使用应用程序域隔离可能导致进程失效的任务。 如果AppDomain的状态是那个 执行任务变得不稳定了 AppDomain可以在没有的情况下卸载 影响过程。这是 当进程必须运行时很重要 长时间没有重新启动。您 也可以使用应用程序域 隔离不应共享的任务 数据
如果程序集已加载到默认应用程序域中,则不能 从内存中卸下 进程正在运行。但是,如果你 打开第二个应用程序域 加载并执行程序集 在那时卸载程序集 应用程序域已卸载。使用 这种技术可以最大限度地减少工 一组长期运行的进程 偶尔使用大型DLL。
可以运行多个应用程序域 在一个过程中;但是,有 不是一对一的相关性 应用程序域和线程。 几个线程可以属于一个 应用程序域,而一个给定的 线程不限于单个 应用领域,在任何给定时间, 一个线程在一个单独执行 应用领域。
可能感兴趣的问题:
我不会自称是AppDomains领域的专家,但我很确定通过卸载AppDomain不会释放COM对象泄漏内存(即非托管内存)。也许更熟悉这一点的人可以发表评论。
正如Brian指出的那样,“...在.NET Framework 2.0版域中无法保证卸载,因为它可能无法终止执行线程。”