为什么Windows 2008在内存满之前使用swap?

Ern*_*ler 9 iis windows-server-2008 .net swap

我管理运行 IIS 和 .NET4 Web 应用程序的 Windows 2008 服务器(好吧,在 Amazon EC2 上)。前几天我收到了内存警报,然后去查看,果然进程内存通过某种缓慢泄漏随着时间的推移而增长。它没有增长太多,就像 60M 到 200M 一样,但由于盒子已经超过了我们相当低的阈值 (75%),所以它已经超出了我们的显示器。

我回收了应用程序的池并释放了内存,我在查看统计信息时注意到交换空间被大量使用,并且通过回收释放了超过 1 GB 的空间。

也许这是一个基本问题,但我是一个 UNIX 人,我习惯于在内存不足之前交换不习惯。这个盒子从来没有超过 75% 的内存使用量。这是 Windows 的东西还是 .NET 的东西还是亚马逊的东西?我怀疑这个应用程序中的内存泄漏比怀疑的要大得多 - 它不是从 60M 泄漏到 200M,而是从 60M 泄漏到 1.2GB,但其中大部分都以某种方式变得“冷”并被推出交换?

我在应用程序池上设置了内存回收,但它触发了盒子满内存,所以这个应用程序可能会在它自动回收之前变得非常非常大。

我可以设置定期的“定时”回收,但这是一种解决方法,我会让开发人员修复应用程序,但需要了解交换使用情况,以确保我正确理解这一点。

使用更多信息进行编辑:实例内存:1.7 GB 交换:4.5 GB

我在 taskmgr 中看到 w3wp.exe 进程显示内存:211,000k。但是当我重新启动它时(它在它自己的应用程序池中,并且它是盒子上唯一的应用程序),它的内存使用量下降到 60M 的正常起始点,并且像 1 GB+ 的交换也被释放了。在 taskmgr 中,我刚刚设置了通常的内存(私有工作集)状态,但通过我的其他监控(Cloudkick)看到了交换更改。今天回过头来看看,进程中的内存恢复到 195M(总共 1.2 GB)并且交换已经从 1.0 GB 攀升到 1.1 GB,并没有完全恢复到原来的位置(随着时间的推移,这是一个缓慢蠕变)。

我不太关心这个特定的应用程序,而更关心只是了解 Windows 何时交换以及它如何使用它,以及通常需要关注给定的 Windows 内存和交换使用情况。

Joe*_*oel 17

Windows 和 linux 有两种不同的页面/交换策略。

Linux

Linux 想要完全避免使用交换空间,并等到最后一刻。如果您在 linux 中看到大量交换,则您的系统可能正在或曾经遇到问题。这种策略有利于最小化整体磁盘 i/o,这是系统中最慢的部分,但对于轻负载和重负载交替周期的系统来说较弱(老实说,这是我们大多数人)。你的负载已经很重的时候现在将被“额外的”磁盘 i/o 负担,或者,换句话说,你需要设计你的服务器构建,着眼于拥有足够的内存,即使在此期间也不交换最高预期加载时间。

视窗

Windows 希望将内存视为页面文件的缓存。您的真实内存始终在磁盘上,但如果可以,它将首先从“缓存”中读取/写入。随着时间的推移,这个策略有利于平衡你的负荷;当系统忙而需要交换页面时,当前页面已经在磁盘上并且已经完成了一半的工作。这种方法在 Windows 还很年轻的时候非常有意义,32MB(忘记 GB)仍然是很多 RAM,并且经常需要使用交换空间是给定的。即使在今天,这对于在轻负载和繁忙负载之间交替的工作负载也有好处,因为它有助于随着时间的推移更均匀地分布磁盘 I/O。

现代 Windows 版本具有额外的优化(例如 SuperFetch),可以在负载较轻时在磁盘和 RAM 中预加载和准备内存页面,以帮助避免在首次加载程序时需要额外的磁盘写入。所有这一切意味着您可以将系统设计为只需要足够的 RAM 来满足低于最高预期负载的需求,因此您仍然可以始终获得至少可接受的性能,同时降低成本。

收敛

这种首先在测试环境中测量或预测负载,然后在负载已知时分配生产资源的概念是系统构建中相对较新的发展,它使成为可能,或者至少是实用的,部分原因是虚拟服务器和云服务器的出现. 根据您的负载,您甚至可以将系统设计为根本不需要交换。在这些情况下,Windows 确实允许您关闭分页并表现得更像 Linux 系统。但是,您必须小心;如果您的系统设计需要比预期更多的内存,您可能会以这种方式陷入困境。

另一方面,现代 linux 内核比以前更愿意机会性地交换到磁盘。所以两个系统之间内存管理策略的差异仍然存在,但现在不像以前那么明显了。两种系统都有其优点,每个系统都会互相观察,看看他们可以复制哪些进步。

  • Linux 不一定会等待最后一刻,除非您显式设置 vm.swappiness=0。默认值 60 时,它将交换一段时间未触及的页面。 (2认同)

Dav*_*ett 7

Windows(以及 Linux 和其他类 Unix 操作系统)会将一段时间未使用的页面移动到磁盘,为缓冲区和缓存腾出空间,以加快活动的 I/O 活动。此外,应用程序通常会分配比立即使用的内存更多的内存 - 这可能会鼓励内核对一些最近在后台未触及的内容进行分页,以便所述应用程序在突然启动时看不到分页延迟使用该分配。

在 Linux 下,您可以通过更改/proc文件系统中的相关“swappiness”值来调整(或阻止)这种行为——毫无疑问,您也可以调整注册表值来改变 Windows 在这方面的行为。

另一件要注意的事情是,当某些内容被分页并稍后读回时,内核不会将其从页面文件中删除,直到文件已满或 RAM 中的页面被更改。这样,如果它需要再次分页该块,它可以这样做而无需实际将页面写入磁盘:内容已经存在。在内存过度使用严重到导致页面文件抖动(大量页面不断被映射进和映射出)的情况​​下,这可以极大地提高性能。您可能会发现某些数据因该内存泄漏而被推出,此后已被读回但未从磁盘中擦除,以防这些页面需要映射或 RAM 以便稍后再次腾出空间。在 Linux 下,“SwapCached”值在/proc/meminfo显示在 RAM 和磁盘上具有相同副本的页面中存在多少数据。Windows 无疑使用相同的优化(或类似的优化),但我不知道在哪里查看发生了多少(毫无疑问,您可以查询相关的性能监视器计数器)。

tl;dr:这是正常的。现代操作系统内核将尝试变得聪明并最大化它可以用作缓存的 RAM 以保存 I/O 操作,并且有时会将数据复制到磁盘和 RAM 中以在需要将这些位分页时保存 I/O之后的 RAM。有可能,尽管可能与直觉相反,以这两种方式使用页面文件,即使您当前的 RAM 并不低,也会提高您的整体性能,而不是降低整体性能。