Understanding low-level memory management

Brien Posey explains how changes made at the DOS level can affect Windows 98 and explores how you can optimize your performance by managing low-level memory.

In these days of high-level operating systems with graphical user interfaces, most people assume that DOS is dead. However, this is simply not true. Windows 98 rides on top of a version of DOS. Even Windows 2000 contains a DOS-like operating system called the Recovery Console that you can use for low-level access to the operating system. In this Daily Drill Down, I'll explain how changes made at the DOS level can affect Windows 98. I'll then explain how to optimize these settings.

Why bother?
Right now, you may be wondering why you should even bother looking at the DOS settings in Windows 98. After all, Windows 98 was designed to function without a Config.sys or Autoexec.bat file. However, what you may not know is that this is possible only because Windows 98 has a Config.sys and Autoexec.bat file built in. These files are contained within the boot files. As I’ll discuss later on, the function of these boot files has radically changed since the days of DOS.

The new structure
As you may recall, five files were responsible for the MS-DOS boot sequence: IO.sys, MSDOS.sys,, Config.sys, and Autoexec.bat. In Windows 98, these files still exist, but they have different purposes. In Windows 98, the IO.sys file takes over the functions of all the previously mentioned files except for This doesn't mean that you can erase your MSDOS.sys file and expect Windows 98 to boot, though. In Windows 98, MSDOS.sys is a text file containing user-definable parameters that control how Windows 98 loads.

As I mentioned, the Windows 98 IO.sys file takes over the functionality of IO.sys, MSDOS.sys, Config.sys, and Autoexec.bat. The following commands are built into the Config.sys portion of IO.sys:

Likewise, these commands are built into the Autoexec.bat portion of the IO.sys file:

The only reason that Windows 98 is able to function without a Config.sys and Autoexec.bat file is because it already has one built in. If you don't believe me, or would like to see this for yourself, you can. Although you can't easily view the commands themselves, you can see the result of them. To do so, rename your Config.sys and Autoexec.bat files so that they won't be loaded at boot up. Next, reboot your PC. As soon as you see the Starting Windows 98 message, start pounding the F8 key. You should see the Windows 98 boot menu; select the Command Prompt Only command. Doing so will load Windows 98 without the graphical user interface. Next, type the following command at the command prompt:

This command displays all the files currently loaded into memory. If no Config.sys or Autoexec.bat settings were present, you'd see only the basic DOS modules loaded. However, as you can see in Figure A, this isn't the case.

Figure A
The built-in Config.sys and Autoexec.bat commands do a lot of work behind the scenes.

If Windows 98 has a built-in Config.sys and Autoexec.bat, you may be wondering why you would ever need one at all. Under normal circumstances, you don't have to create custom configuration files. The reason that Microsoft included the ability for you to create these custom files is in case the built-in commands are insufficient for your needs. For example, by default Windows 98 sets the file handles to 60. However, 60 is insufficient for many programs. Therefore, you can override the default with a custom setting of perhaps 100, via the Config.sys file.

Sure, the built-in commands are a nice touch, but you may be wondering what good they are if they are often insufficient. The built-in commands serve two purposes. First, they guarantee that the operating system will always have sufficient resources to load. Second, they make the initial setup process much easier for novices.

The only reason that Windows 98 even offers a user-configurable Config.sys and Autoexec.bat file is to offer expansion when the built-in settings aren't enough, and for backward compatibility purposes. As you probably know, many hardware components and some programs depend on settings found in the Config.sys and Autoexec.bat files. For example, suppose that you've been asked to work on an older system. If that system contains a legacy sound card, there's a good chance that no Windows 98 driver was ever written for it. In such cases, you can often load the DOS-based driver.

Loading a driver or two may sound trivial, but Windows 98 uses the same basic memory model as DOS 6.22. Although the operating system as a whole can support large amounts of RAM, behind the scenes, it's still that first 640 KB of conventional memory that counts. If you have too many drivers to load in the Config.sys or Autoexec.bat files, it's entirely possible that you could run the system out of memory before Windows even finishes booting. Because 640 KB is such a small amount of memory to work with, it's important to use it wisely. Fortunately, there are some techniques you can use to get the most out of your conventional memory.

Memory management
If you have commands in your Config.sys or Autoexec.bat file that load external drivers, open an MS-DOS Prompt window and type the following command: MEM /C |MORE. When you do, you'll see a screen similar to the one shown in Figure B. As you can see in the figure, the memory that's accessible to DOS is divided into two different types, conventional and upper. Conventional memory, as I said earlier, refers to your computer's first 640 KB. Upper memory refers to the memory between 640 KB and 1 MB.

Figure B
DOS accessible memory is divided into two types, conventional and upper.

As in our figure, there's a very good chance that the upper memory is unused on your machine, since upper memory is unavailable to DOS applications by default. This means that all of your DOS-level drivers are consuming portions of that precious conventional memory. As you might have guessed, the idea is to move as many of these drivers from the conventional memory to upper memory as possible. Although it's easy to move some of your drivers to upper memory, it can be quite a challenge to move enough of them to make any kind of difference.

Obviously, the first step to optimizing your memory is to enable the upper memory if it isn't already enabled. To do so, add the following three lines to the top of your Config.sys file (if there are any existing commands in your Config.sys file that reference Himem.sys, EMM386.exe, or DOS, erase them):

Once you've added these lines, save the changes to your Config.sys file and reboot the computer. When the computer reboots, go to the MS-DOS Prompt window and run the MEM /C |MORE command again. This time, you should see that the upper memory area has been slightly used, although your free conventional memory may actually be lower (for now).

The next thing that you need to do is to make a list of which modules are present in memory and their sizes. For example, you'd write down that Himem.sys is using 1 KB and that EMM386.exe is using 4 KB. Write down all the modules and how much memory they’re using.

Once you've compiled this list, check out the portion of the screen (after you press a key) that tells the size of the largest free upper memory block and write this value down. Once you've compiled all this information, it's time to rearrange your memory usage.

The first thing you should know is that some drivers can't run in upper memory. These include things like Himem.sys, EMM386,, and Remove these items from your list, since they can't be manipulated. You should also be aware that the commands that I told you to add earlier will automatically add a portion of the SYSTEM to the upper memory area. Therefore, don't try to move the SYSTEM either.

Now that you know what you can't move, look at your list to see what you can move. Arrange the items on your list in the order of size ranging from largest to smallest. If possible, rearrange the items in your Config.sys and Autoexec.bat files to load the larger files first. In the Config.sys file, change any DEVICE= commands for the items on your list to DEVICEHIGH=. Likewise, add the letters LH to the beginning of commands in Autoexec.bat that load files that appear on your list.

At this point, reboot your computer and open an MS-DOS Prompt window. Execute the MEM /C |MORE command once more. You should see the conventional memory increase and then upper memory decrease. Don't be alarmed if some items don't go into upper memory. Earlier I had you write down the size of the largest free upper memory block. The upper memory is divided into blocks, each capable of holding a file. The largest free upper memory block indicates the largest file that can be placed in upper memory. For example, if you had 50 KB of free upper memory with the largest free upper memory block being 19 KB, then you wouldn't be able to load anything larger than 19 KB into upper memory. The reason that I had you to go ahead and try to load everything into upper memory regardless of size is that some files are capable of fragmenting themselves. This means that they can reside partially in conventional memory and partially in upper memory.

As you'll recall, I also had you arrange the commands that load your drivers in order of size. I did that so that a small file doesn't grab your largest free upper memory block, thus making that block inaccessible to other programs. However, keep in mind that the Config.sys file always executes before the Autoexec.bat file. If you're calling a lot of small files in Config.sys, there's a good chance that these files could eat up all the free upper memory blocks before Autoexec.bat ever executes. If you have small drivers in Config.sys and want to leave room in the upper memory for a large file in Autoexec.bat, it's best to change the DEVICEHIGH= command that precedes the driver to DEVICE=. This will force the smaller files to load in conventional memory, thus leaving more upper memory for your larger files. With a little experimenting, you should be able to determine a loading sequence that works well, along with the appropriate way to assign programs to conventional and upper memory.

If you still can't get enough memory
If you've manipulated everything but still can't seem to get enough memory, remember that you'll never free up all your conventional memory. However, there is one last hint that you might find helpful. The BUFFERS command in Config.sys affects your memory significantly. Each buffer requires memory. You should determine what the minimum requirements for your programs are and set the buffers accordingly. If you're unsure, try removing the BUFFERS command completely. As I mentioned earlier, Windows is perfectly capable of setting enough buffers automatically for the operating system to load.

If you still run a lot of DOS programs or use a lot of 16-bit drivers, it's easy to run your computer low on conventional memory. In this Daily Drill Down, I've discussed ways of manipulating your computer’s conventional memory so that you get the most efficiency.

Brien M. Posey is an MCSE and works as a freelance technical writer and as a network engineer for the Department of Defense. If you’d like to contact Brien, send him an e-mail. (Because of the large volume of e-mail he receives, it's impossible for him to respond to every message. However, he does read them all.)

The authors and editors have taken care in preparation of the content contained herein, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.

Editor's Picks

Free Newsletters, In your Inbox