WINDOWS中的资源管理 Windows下出现“内存不足”的原因和处理 何宗琦 1997-01-01   笔者先后收到一些读者来信,谈到在16MB的内存配置下运行WINDOWS 3.2的应用程序时仍然出现了“内存不足”的问题。例如中国石油化工总公司规划院王学恩来信问:   “我的微机硬件配置为PCI总线的ALI主板,486DX100CPU,540MB硬盘,16MB内存,S3 64V+显示卡,2MB显存,三洋4倍速光驱。进入WIN32并启动WORD 6.0时系统提示:‘内存不足,WORD6无法启动’。不知是我的16MB内存确实不够,还是系统文件配置不正确。请专家指点迷津。”   一般来说,只要有4MB内存,就可以满足WORD 6.0的基本要求(当然8MB以上的内存更好)。王先生的16MB内存当然不存在物理内存不足的问题。提示信息给出的“内存不足”具有另外的含义。这个问题实际上涉及到WINDOWS的资源管理问题。下面先介绍在WINDOWS中的资源管理,然后再谈谈出现“内存不足”时的处理方法。   WINDOWS作为一个图形环境,在运行时要作大量的图形操作。为了提高速度, WINDOWS提供了一组内部实用程序来完成字体显示和作图等操作,正是这组实用程序组成的“工具箱”使各种图形操作变得十分容易,那些在WINDOWS下运行的应用程序就是利用这个图形“工具箱”来实现自己的图形操作的。这个完成图形操作的程序的文件名是GDI.EXE,它包含了一组用来建立或消除光标、图标、位图、字体等图形操作的例程。此外,WINDOWS中还需要有大量的用户界面操作,如窗口、工具条、对话框、菜单、热键等。这些工作由另一个处理程序USER.EXE负责完成。实际上,GDI.EXE和USER.EXE就是WINDOWS核心程序KRNL286.EXE(标准模式)或KRNL386.EXE(386增强模式)的两个最重要的辅助程序。   在WINDOWS中,把组成用户界面的各个部分如字体、位图、图标、光标、窗口、工具条、对话框、字体、菜单等的实际数据结构称为“资源”,当然字体、位图、图标、光标、窗口、工具条、对话框、字体、菜单等本身也是资源。因此,GDI.EXE和USER.EXE这两个程序就是资源处理程序,所有的资源管理工作都由这两个程序来完成。上述资源是需要有空间来存放的,WINDOWS为GDI.EXE和USER.EXE分别分配了一些内存区来存放这些资源,并称为“资源堆”(当然,如果严格地从程序设计的角度来看,这些用来存放各种资源的内存区称为“堆”并不恰当,但是由于WINDOWS的开发者Microsoft就是这样来命名的)。任何一个在WINDOWS下运行的应用程序所使用的资源都必须纳入这些资源堆中,否则就不能运行。然而,遗憾的是作为一个资源堆的内存区域并不很大,只有64KB。而且资源堆的数量也十分有限。在WINDOWS 3.0中只有一个GDI资源堆和一个USER资源堆,在WIDOWS 3.1中有了改进,允许使用一个GDI资源堆和三个USER资源堆。   这样一来,问题就发生了。尽管从理论上讲,WINDOWS 3.x可以使用4GB的内存空间,但是WINDOWS 3.x本身只能使用四个64KB的内存块作为资源堆。而在这四个不大的资源堆中,要存放WINDOWS及其应用程序运行时的很多必不可少的资源。要存放的资源越多,这四个内存块就越拥挤,而需要存放的资源太多时,就会出现“内存不足”的情况了。这个“内存不足”实际上指的是用作资源堆的“内存”“不足”。而实际的物理内存可能还有很多剩余。这个矛盾有一点类似于磁盘容量和磁盘目录项有限的问题,设想如果不允许使用子目录,而根目录下的目录项又是有限的,则有可能出现磁盘还有剩余空间,而由于目录项用完,不能再写入新文件的情况。   下面,我们再来看看资源堆的实际使用情况。如果仅仅运行WINDOWS 3.x本身(“启动”图标中没有应用软件同时启动运行,在WIN.INI文件中没有由run或load命令加载任何应用程序),那么这四个资源堆内存块只使用了15%,还有85%的空间可供使用。你可以在“程序管理器”的“帮助”菜单中选择“关于程序管理器”,打开一个窗口来检查当前的“可用资源”(实际上指资源堆中可用的剩余空间)。在该窗口中的最后一行为“系统资源:xx%可用”就表示当时的可用资源。   如果再运行其它的应用程序,也会占用这四个内存块的空间,那么剩下的可用资源就会减少。例如:运行WORD时要占用这四个内存块的15-20%左右。如果同时运行中文之星,此时的可用资源就将继续减少。笔者在WINDOWS 3.2下运行中文之星 2.0和WORD 6.0写本文时,检查此时的系统可用资源还剩下58%。而如果剩的资源堆内存块不足15%,WIDOWS就无法正常运行,或者不出现文本,或者窗口不完整等,当然也会拒绝执行另一应用程序。可见,如果运行的程序太多,剩下的资源不足以运行新的程序时,再启动新的程序就会给出“内存不足”(Out of menory)的提示。这个提示给用户造成了物理存储器不够使用的错觉。而实际上,可能还有很大的内存空间并没有被使用。   在WINDOWS 3.0中由于只允许使用两个资源堆,所以“内存不足”的问题经常发生,WINDOWS 3.1虽然有所改进,提供了四个资源堆,但是仍然只有一个GDI资源堆。当然Microsoft没有说明可用资源百分比中,GDI和USER各占多少,用户也无法了解将要运行的应用程序需要占用多大比例的GDI堆和多大比例的USER堆,但是在实际的使用过程中“内存不足”的问题仍然时有发生。这时由于同时运行的应用程序越来越大和越来 越多造成的。这说明四个资源堆仍然可能不够使用,这可能也是WINDOWS 3.1的开发者始料未及的。此外,发生“内存不足”还有一个十分重要的的原因,就是资源回收的问题。理论上讲,一个应用程序在退出运行时有义务释放它所占用的资源,以便其它的程序使用。但是确实有一些应用程序在运行结束之后既不主动释放自己占用的资源,也不通知GDI和USER回收这些不再使用的资源。而且,当一个应用程序出现故障、中止运行时,WINDOWS 3.1也不能收回被它占用的资源。这样,在运行了几个这样的程序之后,可用 资源就已经耗尽。再想运行新的程序时,必然“内存不足”。   在WINDOWS 95中,为了避免“内存不足”问题的发生,作了进一步的改进,一是向用户程序提供了更多用于资源堆的内存块,以供更多更大的应用程序使用。二是提供了防止应用程序在退出后不能回收资源的功能。在WINDOWS 95中使用了一种称为“线程”的机构来管理分配的资源,每一个应用程序在“线程”中都有一个记录,记录了该应用程序占用资源的情况。这样,当一个应用程序中止(非正常中止或者正常退出)时,WINDOWS 95就能够回收它所占用的全部资源。   最后,再谈谈在WINDOWS3.X情况下发生“内存不足”时的处理方法。   从上面的 分析知道,不论你的微机配置了多少物理内存,WINDOWS 3.x能够使用的资源堆都只有四个64KB的内存块。所以,不能用增加内存容量的办法来解决这里所谓的“内存不足”问题。出现“内存不足”问题后一般可以按以下办法处理。首先,退出那些不需要运行的应用程序;然后,再检查系统的可用资源为多少。如果可用资源大于30%,一般可以运行新的程序。当有多个应用程序在系统中运行时,可以退出一个,检查一次可用资源。如果某个应用程序在退出前后,可用资源的百分比没有变化,说明这个应用程序没有释放它所占用的资源;如果要收回这些没有释放的资源只能退出WINDOWS后,再重新进入WINDOWS。为了确保在启动进入WINDOWS时系统的可用资源足够,在“启动”图标中应该没有无关的应用软件同时启动运行,在WIN.INI文件中也没有由run或load命令加载任何无关的应用程序,因为这些同时启动的无关应用程序可能已经占用了很多资源,使得要使用的应用程序无法运行。一般说来,经过这样处理,就不会出现“内存不足”的问题了。