在我开始讨论真正的问题之前,我只想说我可能会在这里得到一些错误的细节.如果是这样,请逮捕我,甚至不要回答我的问题.
我的问题基本上是关于DLL和.NET的.我们有一个使用相当多内存的应用程序,我们正试图弄清楚如何正确地测量它,特别是当问题主要发生在客户端的计算机上时.
让我感到震惊的是,我们有一些相当大的.NET程序集和生成的ORM代码.
如果我使用的是具有唯一基址的非托管(Win32)DLL,则同一台计算机上的多个并发进程会将DLL加载到物理内存中,并将其映射到所有应用程序的虚拟内存中.因此,物理内存将用于此DLL一次.
问题是.NET程序集会发生什么.这个DLL包含IL,虽然它的这一部分可能在应用程序之间共享,但是这个IL产生的JITted代码呢?这是共享的吗?如果没有,我如何衡量以解决这个问题实际上是否导致问题?(是的,我知道,它会有所贡献,但我不会花太多时间在这上面,直到这是最大的问题).
另外,我知道我们没有查看解决方案中所有.NET程序集的基址,.NET程序集是否有必要这样做?如果是这样,是否有一些关于如何确定这些地址的指南?
任何对这一领域的见解都是最受欢迎的,即使事实证明这不是一个大问题,甚至根本不是问题.
编辑:刚刚发现这个问题:.NET程序集和DLL rebasing部分回答了我的问题,但我仍然想知道JITted代码如何影响所有这些.
从该问题及其接受的答案看来,JITted代码放在堆上,这意味着每个进程将加载共享二进制程序集映像,并在其自己的内存空间内生成代码的私有JITted副本.
我们有什么方法可以衡量这一点吗?如果这会产生大量代码,我们必须更多地查看生成的代码,以确定是否需要调整它.
编辑:在此处添加了一个较短的问题列表:
是否有任何意义确保.NET程序集的基址是唯一且不重叠的,以避免重新定义一个主要用于从JIT中获取IL代码的dll?
我如何测量JITted代码使用多少内存来确定这是否真的是一个问题?
@Brian Rasmussen 在这里的答案表明JITting将按照我的预期生成JITted代码的每个进程副本,但是重新组装程序集实际上会减少内存使用量.我将不得不深入研究他提到的WinDbg + SoS工具,我已经在我的列表上停留了一段时间,但现在我怀疑我不能再把它关掉了:)
编辑:我在这个主题上找到的一些链接:
重新安装所有库程序集
MSDN:重新定位Win32 DLL:整个故事
Brian Rasmus.. 6
这是针对问题1)
jitted代码放在特殊的堆上.您可以使用!eeheap
WinDbg + SoS中的命令检查此堆.因此,每个进程都有自己的jitted代码副本.该命令还将显示代码堆的总大小.
如果您需要有关从WinDbg获取此信息的其他详细信息,请与我们联系.
这是针对问题2)
根据专家.NET 2.0 IL Assembly一书.reloc
,纯IL PE文件的一部分只包含一个CLR启动存根的修正条目.因此,在变基期间托管DLL所需的修正量相当有限.
但是,如果您列出任何给定的托管进程,您会注意到Microsoft已经重新设置了其托管DLL的批量(或可能全部).是否应将其视为变基的原因取决于您.
这是针对问题1)
jitted代码放在特殊的堆上.您可以使用!eeheap
WinDbg + SoS中的命令检查此堆.因此,每个进程都有自己的jitted代码副本.该命令还将显示代码堆的总大小.
如果您需要有关从WinDbg获取此信息的其他详细信息,请与我们联系.
这是针对问题2)
根据专家.NET 2.0 IL Assembly一书.reloc
,纯IL PE文件的一部分只包含一个CLR启动存根的修正条目.因此,在变基期间托管DLL所需的修正量相当有限.
但是,如果您列出任何给定的托管进程,您会注意到Microsoft已经重新设置了其托管DLL的批量(或可能全部).是否应将其视为变基的原因取决于您.