在什么情况下.net进程和appdomain会在内存中共享加载的程序集?



我正在寻找有关。net应用程序何时以及如何共享加载的程序集的更多细节。我对操作系统进程之间的共享很感兴趣,但对同一进程内的appdomain之间的共享也很感兴趣。共享程序集通过避免在内存中拥有相同程序集的多个副本来减少系统内存使用,我认为这是主要的好处,但我想知道是否还有其他好处和/或含义。

总结一下我所学到的……

  1. Sysinternals进程资源管理器可以用来列出。net进程的AppDomain和加载到每个AppDomain中的程序集。

  2. . net进程似乎总是将'核心'程序集加载到一个名为'SharedDomain'的AppDomain(可以合理地假设这是在当前进程中的AppDomain之间共享的)。

  3. 任务管理器和进程资源管理器报告了"工作集共享"one_answers"工作集共享"的内存使用情况,但不清楚共享的是什么。(是共享AppDomain内的"核心"程序集吗?其他[非核心]程序集也共享吗?

  4. 在一个简单的测试中,我启动了一个独立的。net应用程序的两个副本,并在每个副本上附加了一个Visual Studio调试器。"模块"视图显示加载的程序集及其在内存中的地址。在我的测试用例中,每个加载的模块位于两个进程中的相同地址。(这是否表示共享,或者这个虚拟地址空间不一定共享?)

  5. ASP。. NET 4.5支持通过一种叫做程序集实习的机制来共享程序集(参见查看在ASP中共享公共程序集)。共享公共程序集,与aspnet_internet .exe共享公共程序集)。它似乎是通过设置文件系统符号链接(symlinks),使不同的web应用程序指向一个共享的bin文件夹工作,因此这提出了一个问题,是否ASP。.NET只是使用符号链接来触发。NET中的标准程序集共享行为,或者是否有更特定于ASP的东西。

。在安装了Visual Studio 2013的机器上,可以在

中找到aspnet_internet .exe。

C:Program Files (x86)Microsoft sdk Windowsv8.1AbinNETFX 4.5.1工具

ASP有进一步的改进。.NET的启动时间和内存使用在更高版本的。NET和Windows Server;看到ASP。.NET应用程序挂起-响应式共享。NET虚拟主机,性能改进。. NET共享主机场景,但我不确定这些变化与这个问题有多大关系。

ASP。.NET程序集共享在介绍。NET 4.5这本书中也有介绍。

还想知道jit代码是否共享,因为加载的程序集由MSIL,资源,元数据等组成,并且在代码被jit时必须分配进一步的内存。

在compact framework中也有关于汇编共享的讨论(We Believe in sharing, MSDN Blogs, Abhinaba Basu)

——更新

我使用sysinternals VMMap工具检查了两个apppool,一个设置了asp.net汇编内部,另一个没有。我还"触摸"了一个测试aspx页面,以使ASP。. NET加载所有程序集(以及全局。asax只运行少量代码,因此会导致一些抖动)。

两个apppool报告的内存使用数据非常相似,Working Set、WS Private和WS Shareable本质上是相同的。然而,WS共享在"实习"应用程序池中要大得多。这是出乎意料的(对我来说),因为没有其他进程可以共享,但是VMMap显示了内存块(标记为'。在实习AppPool中显示为共享内存,而在另一个AppPool中显示为不共享内存的相同程序集。我对此的解释是,进程中的虚拟内存块被映射到相同的物理内存,然后报告为"WS Shared"。

关于装配空间布局随机化。VMMap工具显示了许多具有"映像(ASLR)"类型的内存块。ASLR随机化程序集在内存中的位置以阻止恶意软件,我想知道这是否会阻止程序集实习正常工作。使用EMET工具禁用机器的ASLR确实会使汇编地址更有规律,但不会改变报告的内存数量,因此似乎不会影响汇编实习。值得注意的是,VMMap仍然显示了带有"ASLR"的图像,我怀疑这仅仅意味着程序集/图像被标记为支持/允许ASLR,而不是ASLR有效。

发生程序集共享的一种情况是使用ngen.exe将程序集编译为本机代码。让我引用"通过c#实现CLR"(第1章)

NGen.exe工具在以下两种情况下很有趣:

减少应用程序的工作集-如果您认为一个程序集将同时加载到多个进程中,在该程序集上运行NGen.exe可以减少应用程序的工作集。原因是NGen.exe工具将IL编译为本机代码,并将输出保存在单独的文件中。这个文件可以被内存映射到多进程中地址空间同时,允许代码共享;不每个进程都需要自己的代码副本。

最新更新