到目前为止我学到了什么的总结…
> Sysinternals process explorer可用于列出.NET进程的AppDomains和加载到每个AppDomain中的程序集.
> .NET进程似乎总是将“核心”程序集加载到名为“SharedDomain”的AppDomain中(可以认为这是在当前进程中的AppDomains之间共享的).
>任务管理器和进程资源管理器报告“工作集共享”和“工作集可共享”的内存使用数量不显着,但尚不清楚共享内容. (它是共享AppDomain中的“核心”程序集吗?其他[非核心]程序集是否共享?
>在一个简单的测试中,我发布了一个独立的.NET应用程序的两个副本,并将Visual Studio调试器附加到每个. “模块”视图显示加载的程序集及其在内存中的地址.在我的测试用例中,每个加载的模块位于两个进程中的相同地址. (这是否表示共享,或者这个虚拟地址空间不一定是共享的?)
> ASP.NET 4.5支持通过一个名为assembly interning的机制共享程序集(参见Look at Sharing Common Assemblies in ASP.NET 4.5,Sharing Common Assemblies,Sharing common assemblies with aspnet_intern.exe).它似乎是通过设置文件系统符号链接(符号链接),以便不同的Web应用程序指向一个共享的bin文件夹,因此这引起了ASP.NET是否只是简单地使用符号链接来触发标准的程序集共享行为的问题,还是ASP.NET和IIS AppPools的特定内容呢?
注意.在安装了Visual Studio 2013的计算机上,可以在以下位置找到aspnet_intern.exe:
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1
Tools\
在.NET和Windows Server的更高版本中ASP.NET启动时间和内存使用情况进一步改进;请参阅ASP.NET App Suspend – responsive shared .NET web hosting,Performance Improvements for ASP.NET Shared Hosting Scenarios in .Net 4.5,但我不知道这些更改对这个问题有多重要.
ASP.NET组件共享也在Introducing .NET 4.5本书中介绍.
还想知道JITted代码是否共享,因为加载的程序集由MSIL,资源,元数据等组成,并且当代码为JITted时必须分配进一步的内存.
还有关于在紧凑框架中组装共享的这个讨论(We Believe in Sharing,MSDN Blogs,Abhinaba Basu)
— UPDATE —
我使用sysinternals VMMap tool来检查两个AppPools,一个是asp.net程序集国际设置,另一个没有.我也“感动”一个测试aspx页面,使ASP.NET加载所有程序集(并且一个global.asax运行少量的代码,因此导致一些JITting).
报告的两个AppPools的内存使用量非常相似,工作集,WS Private和WS Shareable基本相同.然而,“共享”AppPool中的WS Shared大得多.这是意想不到的(对我来说),因为没有其他进程要共享,但是VMMap显示的是在实际的AppPool中显示为共享内存的内存块(标记为’.text’和执行/读取保护),而在其他AppPool中的相同程序集不是共享的.我对此的解释是,进程中的虚拟内存块被映射到相同的物理内存,然后被报告为“WS共享”.
ASLR
关于装配空间布局随机化. VMMap工具显示了许多具有“Image(ASLR)”类型的内存块. ASLR将内存中的程序集的位置随机化,以防止恶意软件,我想知道这是否阻止了组装工作正常工作.使用EMET tool禁用机器的ASLR确实使组装地址更加规则,但没有更改报告的内存数,因此似乎不影响装配实习.值得注意的是,VMMap仍然显示“ASLR”的图像,我怀疑只是意味着程序集/图像被标记为支持/允许ASLR,而不是ASLR生效.
解决方法
The NGen.exe tool is interesting in two scenarios:
…
Reducing an application’s working set – if you believe that an assembly will be loaded into multiple processes simultaneously,running NGen.exe on that assembly can reduce the applications’ working set. The reason is because the NGen.exe tool compiles the IL to native code and saves the output in a separate file. This file can be memory-mapped into multiple-process address spaces simultaneously,allowing the code to be shared; not every process needs its own copy of the code.