【问题标题】:Shared libraries (dlls) in memory) - how many copies?内存中的共享库(dll)) - 多少份?
【发布时间】:2014-03-15 11:46:48
【问题描述】:

如果我有两个引用 GAC 中相同库的 .Net 应用程序,并且我同时启动这两个应用程序并执行使用共享库的代码(甚至一个接一个),那么该库的副本数量将是多少?有常驻记忆吗?

我问的原因是我正在尝试提高应用程序中进程的首次执行速度,从 GAC 加载大量库占用了很大一部分首次执行。我正在考虑通过以前运行一个引用和使用相同库的小应用程序来预加载这些(可能在 Windows 启动时)。

要运行的第二个应用程序是否可以访问当前驻留库的同一个副本,还是仍需要加载自己的副本?本能告诉我,只需将一份副本加载到内存中,但事情并不一定如你所料!

【问题讨论】:

  • 关于“.NET冷启动性能”的文献很多,一定要google一下。与内存无关,与磁盘速度有关。
  • 谢谢,我会看看,但我的目标是找到一种方法(如果可能的话)预加载程序集,这样当有问题的应用程序执行时,它不必(因为用户抱怨大约花费的时间)。
  • 告诉他们更频繁地启动它。这样this feature 就会处理它。 SSD 是下一个解决方案。
  • 遗憾的是,SSD 不是解决方案。我们不能仅仅因为我们的应用程序太慢(他们会觉得)就告诉我们的客户在他们所有的 PC 上安装 SSD。

标签: .net dll .net-assembly


【解决方案1】:

GAC 是程序集的“共享”位置,因此您不必在磁盘上保留它们的多个副本,它不是共享内存。因此,在内存中,每个使用它的进程都会有一个 dll 副本。

共享内存,因为在两个进程中使用同一个 dll 实例是完全不同的动物。

如果您正在考虑节省 Jit 程序集所需的时间,因为在您的小应用程序受到打击时,GAC 与此无关。处理这个问题的是 .net 框架本身,它缓存已编译的程序集。因此,鉴于您的小应用程序“运行”程序集,因为它调用了足够的代码来强制 JIT 编译,下一个应用程序将看到一个好处,无论它是否像您希望的那么大还有待观察。这是一个快速的胜利,但是..

所以你更有可能产生持久和可预测的影响,问自己我可以分解我的代码,这样所有这些东西就不必在我可以做任何事情之前全部加载。

【讨论】:

  • 我并不是说 GAC 就是内存(我有 13 年的 C# 应用程序编写经验),我也不打算对它们进行 JIT。我的观点是,一旦一个库被加载到内存中,它是保留在那里并可供随后启动的使用它的应用程序使用,还是在需要时加载自己的副本?
  • @NeilHaughton 从您提出的问题的角度来看,他们会在需要时加载自己的副本。
  • 绝对清楚 - 当两个使用相同 dll 的不同应用程序都被加载并且都在 dll 中执行代码时,内存中是否也有两个 dll 副本?那么运行第一个应用程序并不能让第二个应用程序也不必将 dll 加载到内存中?
  • 是的,加载了两次,否则它们会像在任何对象中一样共享内存,而您必须一直处理它。
  • 谢谢,这清楚了。这也适用于系统(即.Net)库吗?对于每个正在运行的 .Net 应用程序,它们肯定不会一次加载到内存中,或者是吗?
猜你喜欢
  • 2011-12-04
  • 1970-01-01
  • 2021-01-19
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多