我管理一台运行 IIS 和 .NET4 Web 应用的 Windows 2008 服务器(在 Amazon EC2 上)。前几天我收到内存警报,然后去查看了一下,果然,进程内存随着时间的推移通过某种缓慢泄漏而增长。它并没有增长太多,就像从 60M 增长到 200M,但该框中发生了足够多的其他事情,以至于它超过了我们相当低的阈值(75%),从而触发了监视器。
我回收了应用程序池并释放了内存,在查看统计数据时我注意到交换空间已被大量使用,并且通过回收释放了超过 1 GB 的内存。
也许这是一个基本问题,但我是 UNIX 爱好者,我习惯于在内存不足之前不使用交换。此框的内存使用率从未超过 75%。这是 Windows 的问题还是 .NET 的问题或 Amazon 的问题?我怀疑此应用程序中的内存泄漏比怀疑的要大得多 - 它不是从 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 内存和交换使用情况时需要关注什么。
答案1
Windows 和 Linux 有两种不同的页面/交换策略。
Linux
Linux 希望完全避免使用交换空间,并等到最后一刻。如果您在 Linux 中看到大量交换空间,则您的系统可能已经或曾经遇到问题。此策略有利于最大限度地减少整体磁盘 I/O,这是系统中最慢的部分,但对于轻负载和重负载交替的系统(老实说,我们大多数人都是如此)来说,效果较差。负载已经很重的时候现在将受到“额外”磁盘 I/O 的负担,或者换句话说,您需要设计服务器构建,以便即使在预期负载时间最长的情况下也有足够的内存不进行交换。
视窗
Windows 希望将内存视为页面文件的缓存。您的真实的内存始终在磁盘上,但如果可以,它将首先从“缓存”读取/写入。此策略非常适合随着时间的推移平衡负载;当系统变得繁忙并需要交换页面时,当前页面已经在磁盘上,一半的工作已经完成。这种方法在 Windows 刚起步时非常有意义,32MB(忘记 GB)仍然是很大的 RAM,并且经常需要使用交换空间。即使在今天,这对于在轻负载和繁忙负载之间交替的工作负载也很有用,因为它有助于随着时间的推移更均匀地分散磁盘 i/o。
现代 Windows 版本具有额外的优化功能(例如 SuperFetch),可以在负载较轻时预加载并准备磁盘和 RAM 中的内存页面,从而帮助避免首次加载程序时需要额外的磁盘写入。所有这些意味着您可以将系统设计为只需要足够的 RAM 来处理低于最高预期负载的任务,因此您仍然可以始终获得至少可接受的性能,同时降低成本。
收敛
这种首先在测试环境中测量或预测负载,然后在知道负载后分配生产资源的概念是系统构建中相对较新的发展,部分由于虚拟服务器和云服务器的出现而成为可能,或至少是实用的。根据您的负载,您甚至可以将系统设计为根本不需要交换。在这些情况下,Windows 确实允许您关闭分页并使其更像 Linux 系统。但是,您必须小心;如果您的系统设计需要的内存比预期的多,您可能会以这种方式陷入麻烦。
另一方面,现代 Linux 内核比以前更愿意随机交换到磁盘。因此,两个系统在内存管理策略上的差异仍然存在,但现在不像以前那么明显了。两个系统都有自己的优点,并且每个系统都在观察对方,看看自己可以复制哪些进步。
答案2
Windows(以及 Linux 和其他类 Unix 操作系统)会将一段时间未使用的页面移至磁盘,为缓冲区和缓存腾出空间,从而加快活动 I/O 活动。此外,应用程序通常会分配比它们立即使用的更多的内存 - 这可能会鼓励内核在后台分页一些最近未触及的内容,以便当这些应用程序突然开始使用该分配时,不会看到分页延迟。
在 Linux 下,您可以通过改变文件系统中的相关“swappiness”值来调整(或阻止)此行为/proc
- 毫无疑问,您可以调整注册表值来改变 Windows 在这方面的行为。
另一件需要注意的事情是,当某些内容被分页出并随后读回时,内核不会将其从页面文件中删除,直到文件已满或 RAM 中的页面发生更改。这样,如果它需要再次将该块分页出,它可以这样做而不必实际将页面写入磁盘:内容已经存在。这可以在内存过度使用变得非常严重以至于导致页面文件抖动(大量页面不断被映射进和出)的情况下大大提高性能。您可能会发现一些数据被该内存泄漏推出,并且此后已被读回但未从磁盘中擦除,以防这些页面需要映射出或 RAM 以便稍后再次腾出空间。在 Linux 下,“SwapCached”值显示/proc/meminfo
在 RAM 和磁盘上具有相同副本的页面中存在多少数据。Windows 无疑使用了相同的优化(或类似的东西),但我不知道在哪里可以查看这种情况的发生程度(毫无疑问,您可以查询相关的性能监视器计数器)。
总结:这是正常的。现代操作系统内核会尽量聪明地将 RAM 用作缓存,以节省 I/O 操作,有时还会将数据复制到磁盘和 RAM 中,以节省 I/O,以备以后需要将这些位从 RAM 中分页时使用。尽管这可能违反直觉,但这两种方式使用页面文件,即使您目前的 RAM 并不低,也有可能提高您的整体性能,而不是降低它。