有时我打开一个分配过多内存的程序 - 例如计算机有 0.5 GB 的可用内存,而一个应用程序请求 1GB。
在这种情况下,它将开始交换以便能够满足请求。
问题是:它正在做极端交换,包括服务的内存,所以计算机变得非常慢 - 甚至鼠标指针开始卡顿,有时我不得不关闭机器电源。
我觉得不对劲的是,从普通用户帐户运行的用户模式程序可能会导致机器崩溃。
有没有办法告诉 Windows:嘿,如果一个应用程序请求了太多的内存,它是要交换的内存而不是基本服务的内存。
操作系统是 Windows Server 2012 x64,但我也在许多其他机器上看到过这种情况。
答案1
在一个评论,Daniel B 说我遇到了 I/O 匮乏,所以我尝试将交换文件从系统分区(C:)移出并移到一个单独的磁盘。
它确实有效了——当内存压力很大时,计算机不会停止响应。然后我决定对这个问题做一些研究,以便了解为什么这种情况确实会发生。以下是我的结论:
在微软的一份官方文档中“Windows Vista 中的 I/O 优先级”,其中指出 I/O 是分层处理的,并且所有关键优先级 I/O 必须在任何其他优先级 I/O 之前处理。
也有人说关键优先级 I/O 保留给内存管理器。
我找不到内存管理器根据页面所有者进行任何特殊优先级排序的证据(即,交换由较低优先级进程分配的内存页面,并获得较低的 I/O 优先级)。
我找不到 Windows 8 中新优先级策略的任何证据。
因此,假设所有内存管理器 I/O 都具有相同(关键)优先级,并且 I/O 策略自 Vista 以来没有改变,那么这就是灾难的根源:
交换文件与系统位于同一磁盘(通常为 C:)
某个进程请求的内存超出了系统物理可用内存量。
发生交换。交换发生时,其他 I/O 操作都无法进行,即使是系统服务或内核其他组件的必要 I/O 也无法进行,因为关键 I/O 已保留给内存管理器,并且所有关键 I/O 都发生在其他 I/O 之前。
逐渐地,每个阻塞 I/O 的进程都会卡住。最终系统实际上会失去响应。