只有当物理内存超过2GB时才需要/3GB

首先请记住:物理内存和虚拟地址空间不是一回事儿。

我认为,这又是另一个容易令人搞混的两个概念。解物理内存和虚拟内存之间并非简单的一对一的关系。在一般情况下,你所拥有的虚拟内存会远远多于机器上配备的物理内存。空闲物理不会映射到任何虚拟地址空间中,而共享内存在多个虚拟地址空间中实际上是映射到同一个物理内存页面。

这令我想起了另外一则历史小故事。

在Windows 386的古老年代,内核恰好将所有物理内存映射到内核模式虚拟地址空间中。曾有这么一个API函数:_MapPhysToLinear。给它传递一个物理内存范围,它会返回一个返回一段线性地址空间中的一个起始地址,然后我们就可以使用这个起始地址来访问物理内存。有一些驱动开发者发现:内核映射了所有物理内存,然后使用了单一的映射机制。结果就是:开发者调用了_MapPhysToLinear(0, 0x1000),然后只要他们想在将来访问物理内存,他们只需要在返回值上添加一定的偏移量就可以了。换句话说:他们认为存在下面的对应关系:

到了Windows 95的时代,内存管理器被完全地重写了,而上面的等式(也可以说是巧合)不再成立。为了节省内核模式虚拟地址空间,物理内存现在仅在必要时才进行线性映射。

当然,依赖于原有行为的驱动现在就不能正常工作了,因为驱动代码中所依赖的对应关系不再有效了。

所以,当Windows 95启动的时候,它会检查一些常见的驱动模块是否依赖这一行为并被加载了。(Windows 3.1由于不支持动态驱动模块加载,所以它只需要在启动启动的时候检查一次就可以了)

如果发现有这样的驱动模块,则系统会将所有物理内存都映射到内核模式地址空间中,从而确保这些驱动能继续工作。这样的设计虽然浪费了一定的虚拟地址空间,但是它却可以保持驱动模块继续正常工作。

我也经常听到有人说,”微软不应该允许这些带有Bug的驱动继续工作,就应该让这些驱动直接崩溃,这样就可以促使驱动开发者修复他们的问题。”

这意味着,崩溃的原因首先可以追溯到有问题的驱动。内核模式中一个非常常见的野指针的表现是内存损坏,就是说这个模块崩溃的组件很少是首先导致问题的组件。

举个例子,VMM(01)组件中几乎所有Windows 95蓝屏崩溃都是由内存损坏引起的。 VMM(01)组件是 Windows 95 内核的不可交换部分,它是内存管理器所在的位置。如果驱动程序损坏了内核模式堆,则首先出现蓝屏的组件将会是内存管理器。所以,大家明白我们的苦衷了吧?

总结

1) 我们要尽可能地确保软件的兼容性,也就是:能跑起来就尽量让它跑起来。

2) 如果还是不行,就按照第一条。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。

本文来自:《Myth: You need /3GB if you have more than 2GB of physical memory》

最近我写了个东西

正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。

我想:你值得拥有。

主营产品:不锈钢弯头,不锈钢三通,不锈钢大小头,不锈钢法兰