在 w3wp 进程之间共享程序集以减少内存使用
Sharing assemblies between w3wp processes for reduce memory usage
问题 我们在一台机器上发布了很多微服务,即:30 个实例,每个实例使用 150 – 300 MB。
许多微服务使用相同的库,但独立加载。
问题CLR能否加载一次程序集并与其他域共享以减少内存使用?
调查和实验 当我通过 ProcessExplorer 调查这个问题时,我发现每个 w3wp 进程都有 2 个应用程序域。
其中一个用于从 GAC 加载程序集,另一个用于从应用程序文件夹加载程序集。
当我将通用程序集放入 GAC 时。
它增加了Shareable、Shared WS,减少了所有进程的Private WS。但工作集没有变化。
打开VMMap看看w3wp进程的内存结构
- 158 Mb 中的 61 – 图片(加载的程序集)
- 158 Mb 中有 40 个 – 页面文件(与进程关联的内存)
减少内存使用的最简单方法:将多个站点合并到一个应用程序域中。每个站点的启动时间将减少。
如果有很多具有强名称的程序集,您可以将它们放在 GAC 中。它使他们的 domain neutral assembly 用于 w3wp 进程。这样的程序集是 domain neutral 当且仅当它在 GAC 中,并且其传递绑定闭包中的所有程序集都在 GAC 中。 (see also blogs.msdn)
域中性汇编的优缺点:
- (优点)域中性程序集是跨多个应用程序域的程序集
- (优点)域中性程序集将仅被 jitted 一次
- (pros) jitted 代码,以及各种运行时数据结构,如 MethodTables、MethodDescs,将在应用程序域之间共享。
- (缺点)一旦强命名程序集加载到域中,您就无法更新它,因此您应该回收(重新加载)应用程序池。
关于强命名程序集和 GAC 的一些话。
如果您的程序集具有强名称,请确保将它们放在全局程序集缓存 (GAC) 中。
否则,加载程序集需要触摸几乎每一页以验证其数字签名。
当程序集未放置在 GAC 中时验证强名称也会减少 NGen 带来的任何性能提升。
(另请参阅:Pro .NET 性能:优化您的 C# 应用程序。第 289 页)
问题 我们在一台机器上发布了很多微服务,即:30 个实例,每个实例使用 150 – 300 MB。 许多微服务使用相同的库,但独立加载。
问题CLR能否加载一次程序集并与其他域共享以减少内存使用?
调查和实验 当我通过 ProcessExplorer 调查这个问题时,我发现每个 w3wp 进程都有 2 个应用程序域。 其中一个用于从 GAC 加载程序集,另一个用于从应用程序文件夹加载程序集。
当我将通用程序集放入 GAC 时。 它增加了Shareable、Shared WS,减少了所有进程的Private WS。但工作集没有变化。
打开VMMap看看w3wp进程的内存结构
- 158 Mb 中的 61 – 图片(加载的程序集)
- 158 Mb 中有 40 个 – 页面文件(与进程关联的内存)
减少内存使用的最简单方法:将多个站点合并到一个应用程序域中。每个站点的启动时间将减少。
如果有很多具有强名称的程序集,您可以将它们放在 GAC 中。它使他们的 domain neutral assembly 用于 w3wp 进程。这样的程序集是 domain neutral 当且仅当它在 GAC 中,并且其传递绑定闭包中的所有程序集都在 GAC 中。 (see also blogs.msdn)
域中性汇编的优缺点:
- (优点)域中性程序集是跨多个应用程序域的程序集
- (优点)域中性程序集将仅被 jitted 一次
- (pros) jitted 代码,以及各种运行时数据结构,如 MethodTables、MethodDescs,将在应用程序域之间共享。
- (缺点)一旦强命名程序集加载到域中,您就无法更新它,因此您应该回收(重新加载)应用程序池。
关于强命名程序集和 GAC 的一些话。
如果您的程序集具有强名称,请确保将它们放在全局程序集缓存 (GAC) 中。
否则,加载程序集需要触摸几乎每一页以验证其数字签名。
当程序集未放置在 GAC 中时验证强名称也会减少 NGen 带来的任何性能提升。
(另请参阅:Pro .NET 性能:优化您的 C# 应用程序。第 289 页)