GAC 下的所有内容都经过预编译(nened)吗?如果是这样,那么所有 .NET 都是预编译的,所以 CLR 不可能在运行时优化它们?
就像您在应用程序中使用 List 一样,CLR 将无法优化 List 本身,而只能优化它在您的应用程序中的使用方式?这难道不会违背 JIT 的目的,即在运行时获得大量优化吗?如此有效地失去了 BCL 的所有潜在优化?
GAC 下的所有内容都经过预编译(nened)吗?如果是这样,那么所有 .NET 都是预编译的,所以 CLR 不可能在运行时优化它们?
就像您在应用程序中使用 List 一样,CLR 将无法优化 List 本身,而只能优化它在您的应用程序中的使用方式?这难道不会违背 JIT 的目的,即在运行时获得大量优化吗?如此有效地失去了 BCL 的所有潜在优化?
不,GAC 不会自动预 JITted;但是,GAC 是 pre-JIT 的先决条件。实际上,只有一小部分东西是预先 JITted 的。除此之外 - 如果 BCL 是预先 JIT 的,那么 NGEN 已经完成了这些优化,因此“失去所有潜在的优化”不是问题。
GAC 可以包含非 ngen 代码(它必须包含它以及使用 ngen 时的本机图像,因为 ngened 图像不包含所有需要的元数据)。Ngen 的代码需要将 dll 安装在 GAC 中才能有效运行(从技术上讲,您可以不这样做,但生成的名称验证会触发对您的 dll 的完整读取,这可能会使您的启动时间更糟)。
在 3.5 sp1 之前,ngen 编译肯定与运行时编译略有不同,有关更多详细信息,请参阅本文。我想这对于 3.5SP1 仍然适用,因为这些问题很难解决。
由于 ngen 只真正为您带来两个重大胜利,您应该考虑其中一个/两个在您的场景中是否重要,以证明与它们的使用相关的复杂性和成本是合理的。
我建议这篇详细介绍 2.0 ngen 中的一些变化的文章是一本不错的读物,它涵盖了诸如硬绑定之类的内容,这是一个很大的改进,并链接到了关于编写高效托管代码的优秀一般文档,尽管它受到了链接腐烂的影响,请参阅msdn第5章所指。(请注意,该文档很旧,但许多主题仍然有效)
不,全局程序集缓存未预编译。
较新版本的框架确实有一个在后台运行的优化服务,它会进行一些预编译。但是当它在目标系统上运行时,它所做的所有预编译都针对该特定系统进行了优化。
如果从 GAC 加载程序集,则会跳过强名称验证,因为该程序集已经过验证。GAC 的另一个优点是文件保护(仅限管理员)。
NGEN 有自己的本地图像存储。在不先将程序集放入 GAC 的情况下使用 NGEN 有点意义。在这种情况下,加载程序集将导致验证其 SN 签名,这意味着每次加载程序集时都会重新创建加密哈希。
使用 ngen 时的最佳实践是将程序集也放入 GAC。