首页

为什么32位系统上虚拟地址空间是4GB

在一台32位系统上,虚拟地址空间为4GB,这个大小由系统上指针的可用数量决定。 对于一块32位的处理器,一个32位值可以表达232个不同的数值,如果你将每一个数值都指向不同的内存地址,则你就得到了一个232个字节的地址空间,也就是4GB。 如果你愿意放弃平坦内存模型(flat memory model)并使用选择器(selectors),那么你可以将16 位选择器值与32位偏移量组合为一个48位的...

/3GB开关并不能映射一个3GB大小的内存

如果你使用了/3GB,则你得到一个3GB的虚拟地址空间,但这并不意味着你可以映射一个3GB大小的内存块。在这个地址空间中会有一些标准的”空洞”,例如:位于地址空间底部的64KB,以及位于2GB边界的64KB。 而且,系统DLL会继续在它所希望的内存地址加载,这些内存地址通常为于地址空间中的2GB边界下方,另外,进程堆和其他典型的进程结构记录信息也会占用你的虚拟地址空间。结果...

/3GB是一个全局开关  

/3GB开关只会对那些标记为/LARGEADDRESSAWARE的应用程序产生影响。 为了保持兼容性,只有那些明确表明它们能处理超过2GB的虚拟地址空间的程序,才会获得更大的虚拟地址空间。而那些没有这个标记的,只会得到2GB的虚拟地址空间,而位于2GB和3GB之间的空间将不会被使用。 为什么呢? 因为有太多程序假设用户模式虚拟地址的高位总是清晰明确的,这几乎成了一种固有的模式。在MSDN上有一些文...

为什么最近的文章都是关于PAE和/3GB的?

大家可能都注意到了,我最近的几篇文章都是在讲PAE和/3GB相关的主题,可能有一些人已经有点厌烦了,可能这些人还不少。 为什么我要花费差不多两个星期来讲述/3GB开关有关的内容以及一些基础概念,如虚拟内存,虚拟地址空间,物理内存之间的区别? 因为实在是有太多的人没有正确理解/3GB这个开关的真正意义,但是依然假装自己已经理解了。这就比较严重了。 就如你昨天在评论区里所看到的,还是有很多人对于虚拟内...

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

首先请记住:物理内存和虚拟地址空间不是一回事儿。 我认为,这又是另一个容易令人搞混的两个概念。解物理内存和虚拟内存之间并非简单的一对一的关系。在一般情况下,你所拥有的虚拟内存会远远多于机器上配备的物理内存。空闲物理不会映射到任何虚拟地址空间中,而共享内存在多个虚拟地址空间中实际上是映射到同一个物理内存页面。 这令我想起了另外一则历史小故事。 在Windows 386的古老年代,内核恰好将所有物理内...

解惑之所谓的最大2GB可用虚存空间  

咱们先来一个陈述:虚拟内存和虚拟地址空间不是一回事儿。 可能有些人容易将这两个概念弄混,今天来说说。 虚拟地址空间描述了地址是如何被解析,每一个进程都有它自己独立的虚拟地址空间。一个进程使用了多少虚存空间不会对影响其他进程。 假设,我们有一个应用程序进程分配了1GB的虚存空间。然后我们运行这个应用程序的3个实例,这个歌时候,我们将总共分配3GB的虚存空间。 用户模式的虚拟地址空间通常为2GB,但是...

/3GB开关对内核空间的影响

书接上回 /3GB开关的一个不利影响在于,它将内核空间压缩至1GB,从而迫使内核代码必须能在一个较小的地址空间中运行。 对于这个空间限制,最受影响的是显卡驱动程序。为了管理显卡上的内存,显卡驱动需要能访问到这些地址空间,从而需要更多的虚拟空间进行映射操作。当一个显卡驱动需要访问一个256MB的地址空间的时候,这个操作通常不会成功,因为内核中确实没有这么多的可用空间留给显卡驱动程序了。 正所谓:巧妇...

关于经常被误解的一个开关:/3GB

对于/3GB这个开关,其实它做的事情很简单明了,但是还是有一些人们对它有一些误解。今天就来讲一讲。 简单来说,/3GB将会修改默认的4GB虚拟内存空间的分配方式。默认的4GB地址空间将会被分为2GB的用户空间和2GB的内核空间,而如果启用了/3GB开关,则会修改为:3GB的用户空间和1GB的内核空间。 仅此而已,不复杂吧。 但是有些人可能会想着这个开关会做更多的事情。 我想问题可能出在,有些人会觉...

永远不要将焦点设置到一个被禁用的控件上  

在对话框管理这个主题上,其中一个最不应该做的事情,就是:在将一个拥有输入焦点的控件禁用之前,没有将焦点移走。如果出现这种情况,用户在键盘上输入的内容将不会输送至对话框,为什么? 因为一个被禁用的窗口不能接收任何的键盘输入。如果恰好这个时候电脑没有鼠标(举个例子而已,现代的电脑系统,一般都会配备有鼠标),则对话框基本没法以任何方式被用户使用了。 (我曾经在一款微软的软件产品中碰到过这类错误场景,实在...

为什么共享数据分区是一个安全漏洞  

很多人都推荐使用共享数据分区(shared data sections)来在一个应用程序的多个实例中共享数据。这听起来是一个不错的主意,但是实际上,它会带来一个安全漏洞。 使用CreateFileMapping函数创建的共享内存对象可以是很安全的。它使用了安全描述符用来指定使用者被允许的访问级别。而作为对比,任何人都可以加载你的EXE或者DLL文件来访问你定义在文件中的共享内存分区。 下面,我们来...