5

GAC 下的所有内容都经过预编译(nened)吗?如果是这样,那么所有 .NET 都是预编译的,所以 CLR 不可能在运行时优化它们?

就像您在应用程序中使用 List 一样,CLR 将无法优化 List 本身,而只能优化它在您的应用程序中的使用方式?这难道不会违背 JIT 的目的,即在运行时获得大量优化吗?如此有效地失去了 BCL 的所有潜在优化?

4

4 回答 4

4

不,GAC 不会自动预 JITted;但是,GAC 是 pre-JIT 的先决条件。实际上,只有一小部分东西是预先 JITted 的。除此之外 - 如果 BCL 是预先 JIT 的,那么 NGEN 已经完成了这些优化,因此失去所有潜在的优化”不是问题。

于 2009-03-17T21:40:10.743 回答
2

GAC 可以包含非 ngen 代码(它必须包含它以及使用 ngen 时的本机图像,因为 ngened 图像不包含所有需要的元数据)。Ngen 的代码需要将 dll 安装在 GAC 中才能有效运行(从技术上讲,您可以不这样做,但生成的名称验证会触发对您的 dll 的完整读取,可能会使您的启动时间更糟)。

在 3.5 sp1 之前,ngen 编译肯定与运行时编译略有不同,有关更多详细信息,请参阅本文。我想这对于 3.5SP1 仍然适用,因为这些问题很难解决。

由于 ngen 只真正为您带来两个重大胜利,您应该考虑其中一个/两个在您的场景中是否重要,以证明与它们的使用相关的复杂性和成本是合理的。

  1. 这些 dll 的启动时间大大减少
    • 尽管需要生成所有在启动时加载的 dll 以避免加载 jit 本身的开销,但要获得真正的巨大胜利)
  2. 本机映像可以跨多个进程共享内存空间。
    • 如果您只运行一两个进程,那将毫无意义。

我建议这篇详细介绍 2.0 ngen 中的一些变化的文章是一本不错的读物,它涵盖了诸如硬绑定之类的内容,这是一个很大的改进,并链接到了关于编写高效托管代码的优秀一般文档,尽管它受到了链接腐烂的影响,请参阅msdn第5章所指。(请注意,该文档很旧,但许多主题仍然有效)

于 2009-03-17T22:54:16.010 回答
1

不,全局程序集缓存未预编译。

较新版本的框架确实有一个在后台运行的优化服务,它会进行一些预编译。但是当它在目标系统上运行时,它所做的所有预编译都针对该特定系统进行了优化。

于 2009-03-17T21:41:07.950 回答
-2

如果从 GAC 加载程序集,则会跳过强名称验证,因为该程序集已经过验证。GAC 的另一个优点是文件保护(仅限管理员)。

NGEN 有自己的本地图像存储。在不先将程序集放入 GAC 的情况下使用 NGEN 有点意义。在这种情况下,加载程序集将导致验证其 SN 签名,这意味着每次加载程序集时都会重新创建加密哈希。

使用 ngen 时的最佳实践是将程序集也放入 GAC。

于 2009-03-17T21:47:51.520 回答