什么是AppDomain?


118

什么是AppDomain? AppDomain有什么好处,或者为什么微软带来了AppDomain的概念,没有AppDomains的问题是什么?

请详细说明。

  0

另外需要注意的是,ApplicationManager类位于所有正在运行的AppDomain之上。 08 1月. 112011-01-08 18:14:35

104

AppDomain在进程内提供了一层隔离。你通常认为的“每个程序”(静态变量等)实际上是每个AppDomain。这是有用的:

  • 插件(你可以卸载的AppDomain,而不是内的AppDomain组件
  • 安全性(可以运行特定信任级别的一组代码)
  • 隔离(你可以运行不同版本的组件等)

的痛苦是你需要使用远程等

See MSDN了解更多信息。说实话,这不是你经常需要惹恼的事情。

+11

有一点(但很重要)值得一提:AppDomains不包括线程。 22 2月. 092009-02-22 13:04:38

  0

@RüdigerStevens你是什么意思? 30 9月. 152015-09-30 11:53:03

+5

@AgentFire:如果某些线程中运行的某些代码和某个AppDomain从另一个AppDomain调用代码,则该线程“跨越”AppDomain边界并运行来自该另一AppDomain的代码。 因此,线程不属于特定的AppDomain ......尽管可以说线程“属于”域,但是创建它的代码来自该域。但是一个线程可以从任何AppDomain运行代码。 02 10月. 152015-10-02 16:04:46

  0

@RüdigerStevens这实际上是一个优势。 02 10月. 152015-10-02 18:37:20

+2

正如@Marc指出的那样,将AppDomain视为额外的隔离层是一个好主意。我想把它放到上下文中:[Process> CLR> AppDomain> Assembly with statics> Thread with stack]。这意味着一个进程拥有一个公共语言运行时(CLR)。 CLR有一个或多个AppDomain。每个AppDomain加载一个或多个程序集。每个程序集都有自己的静态变量和一个或多个线程。每个线程都有自己的堆栈。 05 7月. 162016-07-05 23:31:06

  0

我想,如果线程不像上下文那样不可知的话,那将是一个抽象泄漏。另外,如果你将线程视为一些在控制流中传输的机器,沿着这条线连续执行命令,你会发现它并不关心这个命令链会引导他,不管它是从它开始的相同域还是另一个。所有命令看起来都很相似,并且在“物理”位置的任何位置都会进行类似的处理。命令起源的概念与我在其一维世界中的线程正交。嘿嘿。 01 8月. 172017-08-01 06:46:59


31

AppDomains可以被视为轻量级进程。它们具有许多与过程相同的特征,例如他们有自己的静态副本,程序集等等,但它们都包含在一个单独的进程中。从操作系统的角度来看,一个进程只是一个进程,无论它包含多少个AppDomain。

然而,与进程不同,AppDomain没有任何线程,除非您明确地创建它们。线程可以在任何AppDomain中运行代码。

AppDomain是同一进程的一部分,因此实际上共享相同的托管堆。这通常不是问题,因为AppDomain编程模型阻止AppDomain之间的隐式访问。但是,一些引用实际上是在AppDomain之间共享的,例如类型对象和实例化字符串。

  0

只是一个音符。 Interned字符串似乎不是在不同的AppDomain之间共享 16 12月. 142014-12-16 08:40:57


41

应用程序域实现了一个连续的虚拟内存空间的概念,该空间包含可直接访问或引用的代码和内存资源。

单独的AppDomain不共享内存空间,因此,一个AppDomain不能直接引用另一个AppDomain中的内容。特别是,数据必须通过按值复制过程在AppDomain之间传递。特别是,依赖指针和内存地址的引用对象必须首先从源代码序列化,然后反序列化到目标AppDomain中。

以前在Windows系统中,内存边界是由进程实现的;然而,构建过程是资源密集型的。它们也作为线程边界的双重用途。另一方面,应用程序域只涉及内存边界或地址空间。线程可以跨AppDomain“流动”(也就是说,一个过程可以调用另一个AppDomain中的入口点,并等待它返回,线程被称为在另一个AppDomain内继续执行)。

这种体系结构的一个显着优势是App域之间的通信模式基本保持不变,无论AppDomain是在同一个进程中,不同的进程还是在不同的机器上在一起:即序列化和反序列化(编组)的参数数据。

注意1:穿过AppDomain的线程的含义是阻塞或同步方法调用到另一个AppDomain(相对于非阻塞或异步调用,这会产生另一个线程继续在目标AppDomain中执行并继续在它当前的AppDomain中没有等待响应)。

注2:有线程本地存储这样的东西。然而,一个更好的名字将是应用程序域线程本地存储,因为线程离开自己的数据,因为他们跨越应用程序域落后,但接他们回来了,当他们返回:http://msdn.microsoft.com/en-us/library/6sby1byh.aspx

注3:一个.NET Runtime是一个Windows进程应用程序与关联的堆。它可能在该堆中托管一个或多个AppDomain。但是,AppDomain的设计是不需要彼此关注的,并且可以通过编组来相互沟通。可以想象的是,可以执行优化来绕开通信AppDomain之间的封送,共享相同的.Net运行时并因此具有相同的Windows进程堆。

  0

好吧,我在你的陈述之间有点困惑**单独的AppDomain不共享内存空间**和@Brian Rasmussen ** AppDomains是同一个进程的一部分,因此实际上共享相同的托管堆**。你能澄清一下吗? 18 8月. 162016-08-18 02:39:12

  0

当AppDomain是同一个Windows进程的一部分(因此在相同的.Net运行时实例中)时,它们将必然位于所述Windows进程的相同托管堆中;但是,.Net应用程序通常不会看到这种情况。请记住,.Net应用程序不是Windows Process应用程序,实际上运行在一种虚拟机中。 18 8月. 162016-08-18 07:19:05