5

在开发应用程序时,我一直在运行“ngen install ...”。但是在覆盖这些程序集之前,还没有在某些版本/场景(调试等)上运行“ngen uninstall ...”。现在我在“C:\Windows\assembly\NativeImages_v4.0.30319_64\AssemblyName\hashkey”形式的文件夹中看到了许多 *.ni.exe 和 *.ni.dll。(dll也是内部开发的。)

我正在使用.Net 4。

反正有卸载这些吗?我已经尝试过“ngen update”,它似乎没有触及这些孤立的原生图像。当然,我可以手动删除这些,但它会扰乱我的程序集所依赖的系统 dll 上的引用计数,或者对 .net 系统产生更严重的后果。

除了占用空间之外,这些旧程序集还会损害启动延迟,因为程序集绑定程序试图将当前 IL 与每个本机程序集匹配。

还有比使用命令行更好的方法来查看本机图像缓存中的内容吗?

谢谢

4

2 回答 2

5

虽然这个问题已经有了答案,但如果要删除陈旧(旧)的 ngen 化程序集,则需要考虑一些事项。

  • 确保检查 NGen 是否认为它们已安装并在执行时使用相同的 NGen(CLR 版本,32 位/64 位)ngen display。使用ngen display yourasm.dll将不起作用(在文件名上),但ngen display AssemblyName会(内部程序集名称)。您可以使用部分名称。
  • 当您使用 时ngen uninstall,按照您安装它们的相反顺序卸载它们。依赖不会被卸载,但是如果你在安装依赖程序集之前手动安装了依赖项,则需要先卸载依赖程序集:

    • 如果 A 依赖于 B 和 C 并且 B 依赖于 C,那么你做了:

      ngen install B
      ngen install C
      ngen install A
      

      那么您只能通过以下方式卸载它们:

      ngen uninstall A  // removes A, if nothing is dependent on it
      ngen uninstall C  // removes C, it has no dependencies now
      ngen uninstall B  // removes B, it has no dependencies now
      
    • 如果您不确定依赖关系,请检查 的输出ngen display asmname,它将列出“ROOT”下的依赖关系。必须先删除那里的任何东西

    • 如果另一个应用程序使用您的任何文件,您需要先卸载该应用程序
    • 如果发现使用以下命令检查c:\windows\assembly\NativeImages_v4.0.30319_64(和*_32版本)是否仍然安装有帮助:

      dir | findstr "AsmName"
      

      由于这里有很多文件,因此有助于查看仍然存在的文件。它还有助于找出它们属于哪个版本(32 位、64 位、MSIL)。这似乎对他们放在那里的个人资料没有帮助。

  • 我注意到该c:\windows\assembly文件夹​​的 Windows 资源管理器视图未显示已生成的程序集,但未显示 GAC 中的程序集。但是,如果您的程序集也在 GAC 中,您可以通过右键单击然后选择“卸载”从 GAC 和 NGen 缓存中卸载它。

除此之外,有很多陈旧的图像不会影响性能。CLR 根据程序集名称(名称、版本、公钥令牌)和其他一些启发式方法(文件日期、内部创建日期、哈希)将文件存储在这里。它甚至不会触及您的旧图像。您可以通过使用 Process Monitor 来验证这一点(它只会尝试根据哈希等从一个位置加载经过生成的图像)​​。但我同意,把它们留在身边是很讨厌的。

于 2016-09-03T22:47:34.320 回答
1

ngen uninstall AssemblyName应该管用。AssemblyName可以是部分或完整的程序集名称。

于 2013-11-08T06:08:57.907 回答