DLL,内存映射,基地址,内存使用情况和.NET? [英] DLLs, memory mapping, base address, memory usage, and .NET?

查看:90
本文介绍了DLL,内存映射,基地址,内存使用情况和.NET?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我开始真正的问题之前,我只想说我可能弄错了这里的一些细节.如果是这样,请就这些问题逮捕我,甚至不要回答我的问题.

Before I start with the real question, let me just say that I might get some of the details here wrong. If so, please arrest me on those as well as, or even instead of answering my question.

我的问题基本上是关于DLL和.NET的.我们有一个使用大量内存的应用程序,并且我们试图找出如何正确测量此问题的方法,尤其是当问题主要发生在客户端计算机上时.

My question is about DLLs and .NET, basically. We have an application that is using quite a bit of memory and we're trying to figure out how to measure this correctly, especially when the problem mainly occurs on clients' computers.

让我大吃一惊的是,我们有一些相当大的.NET程序集,它们带有生成的ORM代码.

One thing that hit me is that we have some rather large .NET assemblies with generated ORM-code.

如果我使用的是具有唯一基址的非托管(Win32)DLL,则同一台计算机上的多个并发进程会将DLL一次加载到物理内存中,然后将其映射到所有应用程序的虚拟内存中.因此,该DLL将只使用一次物理内存.

If I were using an unmanaged (Win32) DLL that had a unique base-address, multiple simultaneous processes on the same machine would load the DLL once into physical memory, and just map it into virtual memory for all the applications. Thus, physical memory would be used once for this DLL.

问题是.NET程序集会发生什么.该DLL包含IL,尽管它的这一部分可能在应用程序之间共享,但是由该IL产生的JITted代码又如何呢?共享吗?如果不是,我该如何测量以找出实际上是导致该问题的原因呢? (是的,我知道,它会有所贡献,但是在这是最大的问题之前,我不会花很多时间在上面).

The question is what happens with a .NET assembly. This DLL contains IL, and though this portion of it might be shared between the applications, what about the JITted code that results from this IL? Is it shared? If not, how do I measure to figure out of this is actually contributing to the problem or not? (Yes, I know, it will contribute, but I'm not going to spend much time on this until it is the biggest problem).

此外,我知道我们没有在解决方案中查看所有.NET程序集的基址,.NET程序集是否需要这样做?如果是这样,是否有一些指南可用于确定这些地址?

Also, I know that we haven't looked at the base address for all the .NET assemblies in our solution, is it necessary for .NET assemblies to do so? And if so, are there some guidelines available on how to determine these addresses?

即使事实证明这不是一个大问题,甚至根本不是问题,对这一领域的任何见识都将受到欢迎.

Any insight into this area would be most welcome, even if it turns out that this is not a big problem, or not even a problem at all.

编辑:刚发现以下问题: .NET程序集和DLL rebasing 可以部分回答我的问题,但是我仍然想知道JITted代码是如何将所有这些因素考虑在内的.

Edit: Just found this question: .NET assemblies and DLL rebasing which partially answers my question, but I'd still like to know how JITted code factors into all of this.

从该问题及其已接受的答案看来,JITted代码位于堆中,这意味着每个进程将加载共享的二进制程序集映像,并在其自己的内存空间中生成代码的私有JITted副本.

It appears from that question and its accepted answer that the JITted code is placed on a heap, which means that each process will load up the shared binary assembly image, and produce a private JITted copy of the code inside its own memory space.

我们有什么办法可以衡量这个?如果结果产生了大量代码,我们将不得不更多地查看生成的代码,以找出是否需要调整它.

Is there any way for us to measure this? If this turns out to produce a lot of code, we'd have to look at the generated code more to figure out if we need to adjust it.

编辑:在此处添加了一个简短的问题列表:

Edit: Added a shorter list of questions here:

  1. 是否有必要确保.NET程序集的基址是唯一的且不重叠的,以免重新建立DLL,而该DLL主要用于将IL代码用于JITting?
  2. 我该如何测量JITted代码使用了多少内存来确定这是否确实存在问题?

@Brian Rasmussen 的答案

The answer by @Brian Rasmussen here indicates that JITting will produce per-process copies of JITted code, as I expected, but that rebasing the assemblies will actually have an effect in regards of reduced memory usage. I will have to dig into the WinDbg+SoS tools he mentions, something I've had on my list for a while but now I suspect I can't put it off any longer :)

编辑:我在该主题上找到了一些链接:

Edit: Some links I've found on the subject:

  • Rebase all your library assemblies
  • MSDN: Rebasing Win32 DLLs: The Whole Story

推荐答案

这是关于问题1)

固定代码放置在特殊的堆上.您可以在WinDbg + SoS中使用!eeheap命令检查此堆.因此,每个进程将拥有自己的jitted代码副本.该命令还将显示代码堆的总大小.

The jitted code is placed on a special heap. You can inspect this heap using the !eeheap command in WinDbg + SoS. Thus every process will have its own copy of the jitted code. The command will also show you the total size of the code heap.

如果您需要有关从WinDbg获取此信息的其他详细信息,请告诉我.

Let me know if you want additional details on getting this information from WinDbg.

这是问题2)

根据这本书 Expert .NET 2.0 IL Assembly ,纯IL PE文件的.reloc部分仅包含一个CLR启动存根的修订项.因此,在重新定基期间,托管DLL所需的修复数量非常有限.

According to the book Expert .NET 2.0 IL Assembly the .reloc part of a pure-IL PE file contains only one fixup entry for the CLR startup stub. So the amount of fixups needed for a managed DLL during rebasing is fairly limited.

但是,如果列出任何给定的托管进程,您会注意到Microsoft已经重新建立了其托管DLL的大部分(或全部)基础.是否应将其视为重新定级的原因取决于您.

However, if you list any given managed process, you'll notice that Microsoft has rebased the bulk (or maybe all) of their managed DLLs. Whether that should be viewed as an reason for rebasing or not is up to you.

这篇关于DLL,内存映射,基地址,内存使用情况和.NET?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆