INF: What EMS Means to Developers

ID Number: Q30590

2.03 2.10 3.00

WINDOWS

Summary:

This article describes how using Windows expanded memory affects

application development.

Please note that when expanded memory is mentioned in this article, it

also means extended memory. Extended memory is used as expanded memory

by Windows.

More Information:

In Windows versions 2.x and 3.0, expanded memory can be used by the

Windows memory manager. In enhanced mode Windows 3.0, the memory

manager can emulate expanded memory by using extended memory. All

Windows applications are run in one virtual machine, but each DOS

application receives its own virtual machine in which to run.

In real mode Windows, expanded memory presents the following problems:

1. Applications cannot share memory through global handles

2. The efficient use of available EMS (expanded memory specification)

in a small frame

The only way applications can share global data is through the dynamic

data exchange (DDE) protocol or through the clipboard. When large

frame EMS is used, global objects are allocated above the EMS line and

are available only to one application. For example, in large frame

EMS, task A allocates some global memory and passes the handle to task

B. When task B attempts to access the memory object, it will not be in

memory. Instead, task B will access the corresponding location in its

own EMS memory.

DDE and clipboard objects can be shared because the Windows memory

manager will copy the contents of these objects to the currently

running application's EMS bank. The application must check the return

value from GlobalLock() because the memory manager may not be able to

successfully copy the object in a low memory situation. Clipboard

objects should be copied by the receiving application before the

clipboard is closed because the memory manager may delete the global

object.

Applications can share data through dynamic-link libraries (DLLs), as

well as through DDE and clipboard objects; however, only data located

in the DLL data segment can be shared. Global objects allocated by

DLLs are allocated above the EMS line, just like objects allocated by

an application.

There is one exception to the rule of not sharing global memory

handles. If the GMEM_NOT_BANKED flag is used, the object will be

allocated below the EMS bank line, making it available to all

applications. This should not be done because there is only a limited

amount of memory below the EMS line when the system is using large

frame EMS. This flag is available for device drivers that require this

kind of shared memory; applications should be designed using one of

the other methods to share memory objects.

The second issue regards the most effective use of small frame EMS by

applications. In small frame EMS, code and resources are the only EMS

items available to applications. Once code and resources are loaded

into EMS, they will not be discarded. However, they are banked out

when another task is running.

The Windows loader fills EMS before it loads code or resources into

conventional memory. For this reason, the DEF file for each

application should list the segments that are important throughout the

life of an application at the top of the list of segments in the

SEGMENTS statement, and these segments should be marked as PRELOAD.

List the segment that contains the application's main window procedure

first. The segments for code that is used and discarded, such as

initialization code, should be listed toward the bottom of the list.

By the same reasoning, mark resources that are important throughout

the life of the application as PRELOAD.

For small applications, the LimitEmsPages() function allows an

application to limit the amount of EMS that is allocated on its

behalf. The argument passed to this function is the maximum number of

kilobytes of EMS that Windows will allocate for the application. A

small application can call this function to keep 400-500K of EMS from

being allocated when the application can run reliably with 100K of

EMS.

When LimitEmsPages() is used, it is important to note that in large

frame EMS (where DLL code is located above the EMS line), a small

application will require more space than the sum of its segments

because library code shares the EMS allocated for the application.

Note: Hook callback functions must be placed in FIXED DLL code so the

code will always be present regardless of EMS state. The same is true

for GlobalNotify() callback functions.

Additional reference words: 2.03 2.10 3.00