Many users of DOS have, at one time or another, seen the
error message "out of memory." This message gives many people
grief, because it is cryptic and means absolutely nothing to them.
What it means is this:
A lot of programs today require more than 600 KB of conventional
memory just to run the program, and their data will require even more
memory. Many systems do not have enough conventional memory to accommodate
these requirements, so when users try to load these programs, they
encounter the "out of memory" situation.
Learning how to use your memory as efficiently as possible
should help in alleviating a lot of these types of problems.
This article teaches some simple techniques to ensure that you
get the most out of your system. It then covers, in more detail, some
"tricks" to get even more memory.
There are two ways to optimize the memory used with PC DOS 2000. The
first and simplest way is to use the program RAMBOOST. Included with
PC DOS 2000, RAMBOOST is an automatic memory optimizer. By running RAMSETUP,
you can start the installation process of RAMBOOST.
One nice feature of RAMBOOST is that, when a program or the user changes
the CONFIG.SYS or AUTOEXEC.BAT file, RAMBOOST automatically detects
the change and re-optimizes the memory in the system.
RAMBOOST has two modes of optimization. The default mode is the less
aggressive. When running RAMBOOST, if you get less memory than you
expected, try changing to the other optimization method. This is done
by editing the C:\DOS\DATA\RAMBOOST.INI file. In this file, the setting
optmethod=2 is the default value. If you change this value
to optmethod=1, RAMBOOST performs an aggressive memory
optimization which may take a bit longer to finish.
The other method to optimize memory is to do it manually. Optimizing
memory manually is relatively easy, and should provide good results
once the user knows what memory optimization is all about. The major
purpose of this article is to discuss manual memory optimization.
Memory
To begin with, let's discuss memory. What is it? What are you running
out of? You have 8 megabytes, but you can't run a 400 KB file --
why not?
There are three types of memory that a person needs to know
about
when optimizing a system, as illustrated
in Figure 1. Each of these types is discussed in
detail.
Conventional Memory:
Conventional memory is the memory that many DOS programs
need the most, and is therefore the memory that we try to free up
when optimizing our systems.
The first 640 KB of memory is known as conventional memory. 640 KB
is equivalent to 655,360 bytes and also to A0000 hexadecimal bytes
(written as A0000h). When referring to memory, most programmers use
hexadecimal equivalents.
Figure 1 shows the end of conventional memory at the address A000.
This is not a typographical error; when referring to address locations
in DOS, the true address is divided by 10h.
The programs that generally must reside in conventional
memory and
cannot be moved to another location are listed
in Figure 2.
Upper Memory:
The upper memory area, in an 80386 processor or higher,
is memory into which we try to load as many of our running programs
as possible. Loading as many programs as possible into upper memory
frees up the amount of conventional memory that many DOS applications
consider as a critical resource.
Upper memory is accessible by having three statements in your CONFIG.SYS
file:
DEVICE=C:\DOS\HIMEM.SYS
DEVICE=C:\DOS\EMM386.EXE
DOS=UMB
HIMEM.SYS is the driver that enables programs to access extended memory
(XMS). To run HIMEM, you need to have an 80286 system or higher. Extended
memory is memory that resides higher than the HMA. For example, when
a system that has 8 MB of memory, it usually means that, with DOS,
the system has roughly 1 MB of memory in the conventional and upper
memory areas, and 7 MB of extended memory. Extended memory has
no effect on memory optimization.
EMM386.EXE is the driver that allows DOS users to access the upper
memory area. This driver requires HIMEM.SYS to be loaded, and also
requires at least an 80386 system. EMM386.EXE is also the driver,
with the appropriate parameters, that allows access to expanded memory
(EMS).
Most programs today can use XMS to access memory above the first 1
MB, and using XMS is the preferred method of access for a user who
wants to gain the most possible conventional memory. When you use
the RAM option with EMM386.EXE, it turns on EMS, and automatically
uses 64 KB of upper memory. On the other hand, if you have no programs
that require EMS, I recommend using the NOEMS parameter, as follows:
DEVICE=C:\DOS\EMM386.EXE NOEMS
The statement DOS=UMB instructs DOS to make a connection
between conventional memory and upper memory. This then allows you
to load device drivers and programs via the DEVICEHIGH, INSTALLHIGH,
and LOADHIGH commands.
There is also another command that can be added to the CONFIG.SYS:
The DOSDATA=UMB command attempts to move a lot of the
system data into a UMB, thus saving a large amount of conventional
memory.
The upper memory area consists of memory between the end of conventional
memory (A000) and the beginning of the high memory area (10000). There
are 384 KB (393,216 bytes) in the upper memory area.
Several things already occupy the upper memory area, as
listed in
Figure 3.
Several address locations in Figure 3 can be combined to create an
upper memory block (UMB). The areas that cannot be used to create
a UMB are ROM (read-only memory) locations. These are locations the
computer uses and cannot give away to create a UMB.
When optimizing the computer, you try to get as much memory as possible
for UMB space. The more UMB space you get, the more programs you can
load into upper memory rather than having them reside in conventional
memory.
For instance, if a computer does not have a monochrome adapter (as
is true of most systems sold today), the monochrome area can be included
as a UMB. The way to do this is:
DEVICE=C:\DOS\EMM386.EXE I=B000-B7FF
The parameter I tells EMM386 that the addresses B000 through
B7FF can be included as a UMB.
EMM386 tries to automatically figure out which addresses are free
on your particular system, and for the most part, it succeeds. In
some cases, however, an adapter (such as a Token Ring card) may require
some ROM that occupies some of the General address locations; for
example, a Token Ring card may have ROM that uses addresses from C000-C7FF.
In most cases, EMM386 will realize that it can't use C000-C7FF; but
in the odd chance that EMM386 doesn't automatically figure it out,
the X command can be used to exclude particular addresses.
Its syntax is:
DEVICE=C:\DOS\EMM386.EXE X=C000-C7FF
This statement specifically excludes addresses C000 through C7FF as
potential space within a UMB.
Other commands (listed in Figure 4)
that attach to
the EMM386.EXE statement can assist in getting the most UMB space possible.
High Memory Area:
High Memory Area (HMA) is located between the end of the
upper memory area (10000) and 11000. This area is used primarily by
DOS so that it can move a good portion of itself out of conventional
memory and into the HMA. The HMA is activated by issuing the following
commands in CONFIG.SYS:
DEVICE=C:\DOS\HIMEM.SYS
DOS=HIGH
Recall from above that EMM386 requires HIMEM, and HIMEM is required
to issue the DOS=HIGH command.
When you place both the DOS=HIGH command and the HIMEM.SYS device
driver into your CONFIG.SYS, DOS moves a good portion of itself into
the HMA, thus saving a significant amount of conventional memory.
Another handy switch that saves some memory is the /FASTA20 switch,
which is added as follows:
DEVICE=C:\DOS\HIMEM.SYS /FASTA20
This switch saves some additional memory on machines that support
this switch.
Simple Memory Optimizations
There are several simple rules of thumb for optimizing memory.
(1) In CONFIG.SYS, change all DEVICE= statements
to DEVICEHIGH= and change all INSTALL= statements
to INSTALLHIGH=. Also ensure that DOS=HIGH,UMB,
DOSDATA=UMB, and both HIMEM.SYS and EMM386.EXE are loaded.
(2) In AUTOEXEC.BAT, insert LOADHIGH in front of
each command that loads programs (e.g., LOADHIGH C:\DOS\SMARTDRV).
LOADHIGH can be shortened to LH.
Recovering from Unsuccessful Bootup:
After doing steps 1 and 2, if you reboot the system and
it hangs up while loading, it is likely that you tried to load something
into a UMB that doesn't work well in a UMB. To determine which program
may be at fault, reboot the system, and when "Starting PC DOS"
appears on the screen, hit the F8 key. This enables you to load individual
lines in CONFIG.SYS and then AUTOEXEC.BAT. Continue to type Y
until the hang occurs.
Once the hang occurs, look at the command you had just been executing
(it should be the last thing on the screen). Write down the command
that had just executed, and reboot the system again.
This time, when "Starting PC DOS" appears on the screen,
hit F5. This skips loading CONFIG.SYS and AUTOEXEC.BAT altogether.
Then, you should be able to remove DEVICEHIGH, INSTALLHIGH, or LOADHIGH
from the command that had hung up the system previously.
Several Memory Optimization Techniques
Sample CONFIG.SYS and AUTOEXEC.BAT files that includes
several general
memory optimization techniques are given in
Figure 5.
Advanced Memory Optimizations
This section is geared to users who thoroughly understand the preceding
information, and would like to learn some more advanced techniques
for gaining the optimum amount of memory.
MEM:
The MEM command, which you run from the DOS prompt, shows
the amount of memory that is available in the different areas of the
system. MEM has several switches for displaying additional information,
but we are concerned here only with the /D (Debug)
switch. The command's syntax is:
MEM /D
The MEM command displays the locations and sizes of all loaded programs.
MEM /D displays lists of the programs located
in both conventional and upper memory.
Figure 6 displays output from the
MEM /D
command called
"Conventional memory detail." By looking at the list of programs
in Figure 6, you can see which programs are still being loaded into
conventional memory.
In Figure 6 are several pieces of information. The "Segment"
field gives the address where the program is loading. (Refer to
Figure 1.) The "Size" field describes the size of that
particular program. In the "Name" field, three entries have
indented subentries. For example, the program IBMBIO, at segment 0023F
with total size 4976 bytes, has three subprograms: XMSXXXX0, DPMSXXX0,
and EMMXXXX0. Finally, the "Type" field elaborates on the
type of program that was loaded. For example, XMSXXXX0 was recognized
as an installed driver called HIMEM.
The types of programs that are generally loaded into conventional
memory and cannot be wholly moved into upper memory are HIMEM, EMM386,
and the system drivers. In Figure 6, the last five lines listed --
the installed driver RAMDRIVE and the programs DOSKEY, MSCDEX, SMARTDRV,
and MOUSE -- are the most likely files to move into a UMB if there
is enough room.
In the "Upper memory detail" output from MEM
/D
(Figure 7),
information is displayed for the free space as well as
the programs that reside in the upper memory areas. The information
displayed for upper memory is similar to that in the conventional
memory display, with one exception: In the upper memory display, a
"Region" field has been added.
Regions are basically upper memory blocks. Recall that, earlier in
this article, you may have added to the EMM386 line the command
I=B000-B7FF.
This created an additional block of memory in the upper memory area.
The addresses located within this range are represented in Figure
7, as well as other blocks of memory that EMM386 has found. In all,
Figure 7 shows four regions, or four different UMBs, into which programs
can be loaded.
In Figure 7, the sections that have the type "-- Free --"
are available to load programs into. Region 1 has a 4 KB block free;
region 2 has a 5 KB block free; region 3 has a 26 KB block free; and
region 4 has a 32 KB block free. Armed with this information, you
can selectively load programs into different regions of memory.
Having looked at the conventional memory detail, you know you have
several programs that could get loaded into a UMB -- a small program
called DOSKEY (about 1 KB), then MSCDEX (about 13 KB), and so on.
How do you load these programs into specific regions of memory? Let's
look at the statements in CONFIG.SYS that loaded RAMDRIVE, DOSKEY,
and MSCDEX initially:
DEVICE=C:\DOS\RAMDRIVE.SYS
C:\DOS\DOSKEY
C:\DOS\MSCDEX /D:IBMCD001 /E
Figure 7 shows that there are 4,320 bytes of free space available
in region 1. Therefore, there is room in region 1 for RAMDRIVE, which
occupies 432 bytes, so let's load RAMDRIVE into region 1 with the
statement:
DEVICEHIGH=/L:1 C:\DOS\RAMDRIVE.SYS
where /L:1 specifies "Load into region 1." This
DEVICEHIGH= statement replaces the original DEVICE=
statement for loading RAMDRIVE.SYS.
Having loaded RAMDRIVE into region 1, there are now 4,320 minus 432
= 3,888 bytes of free space remaining in region 1. Therefore, there
is also room for DOSKEY in region 1, so let's load it there by replacing
the C:\DOS\DOSKEY command with:
LOADHIGH /L:1 C:\DOS\DOSKEY
There are now 3,888 minus 1,152 = 2,736 bytes of free space remaining
in region 1. This size is too small for relocating any more moveable
files.
Region 2 does not have sufficient free space, but region 3 does. Region
3 has 26,512 bytes of free space, and MSCDEX occupies 13,520 bytes,
so let's load MSCDEX into region 3 by replacing the C:\DOS\MSCDEX
command with:
LH /L:3 C:\DOS\MSCDEX /D:IBMCD001 /E
Similarly, the MOUSE program (17,072 bytes) can be loaded into region
4 (32,752 bytes).
Sometimes you may need to shuffle programs around within different
regions so that they all fit as well as possible. For example, note
that there is room in region 4 for both MSCDEX and MOUSE. Loading
both programs into region 4 will leave all 26,512 bytes of free space
in region 3 available for other (perhaps larger) files.
Manual Optimization Is an Art
Optimizing memory manually is an art, and there are things that you
need to look out for. For instance, some programs, when loaded high,
do not successfully load into space where they should fit. As an example,
a program in conventional memory is about 6 KB in size. You have a
7 KB free block in region 2. You try to move this program into region
2, but it won't fit. Why not? Because some programs, when loading,
need more memory while initializing than after initializing. Your
6 KB program may actually require 8 KB to initialize, so in effect
you are asking DOS to stuff an 8 KB program into a 7 KB block.
The Full Benefits of Memory Management
With the information in this article, you have all the tools necessary
to get the most memory out of your system, and to reap the full benefits
of PC DOS 2000's memory management and optimizations.