Article Title: Windows Memory Allocation Limitations
Article Name: WINDOWS1
OS Platforms: WINDOWS
Last Updated: 03/31/2003

TOPIC:

While unthinkable only a few years ago, tumbling memory prices and increasing hard drive capacities have presented PC users the ability to access gigabytes of memory at relativity low cost. As a result of this hardware environment, users are attempting to access large areas of contiguous memory in IDL, but failing for various reasons. This document outlines some of the limitations affecting memory allocation and how they related to IDL. While focused on the Windows operating system, most of the described issues related to any modern operating system.

DISCUSSION:

Limiting Factors When a process requests memory from the operating system, various factors determine if the request will be successful or not. The major factors that can cause a request to fail include:

Available Memory
The actual amount of memory available on the system.

OS Limits
The operating system has limits to the amount of memory that it can support.

Memory Fragmentation
Affects the size of contiguous memory blocks available to the process.

The details of these limitations are discussed in the following sections.

Available Memory

Issue:
This is a fairly straightforward issue: if the amount of memory requested exceeds the amount available the request will fail. To determine the amount of free memory, the operating system takes in the following factors:

Physical Memory    The amount of physical memory (RAM) available to the system.

Virtual Memory    The amount of virtual memory available on the system. Modern operating systems us special areas on hard drives to present a set of memory to the system that exceeds the amount of physical memory.

Memory systems on modern operating systems, Virtual Memory Managers (VMM), segregate memory into blocks or pages of a specific size. Pages that aren't being accessed by the current process are copied to the hard drive page file (sometimes referred as a swap file) and retrieved to physical memory when requested. This action allows memory used to exceed actual physical memory and still maintain system performance.

While more sophisticated than this simple description, by using space located on the hard drive the Virtual Memory Manager is able to present a memory pool that exceeds the size of the physical memory on the system.

Free Memory    While the system might have a large amount of memory available, if that memory is in use, the memory request will fail. The operating system, other process and other memory requested by the application effect the pool of available memory. If a memory request fails, closing other running applications could release enough memory to allow it to succeed.
Solution:

  • Exit any executing applications.
  • Purchase more memory for the system.
  • Increase the virtual memory manager's page file size.

Operating System Limits

Issue:
Another main factor that can affect the amount of free memory are operating limits: In particular the size of the address space available to a process.

To present a uniform memory model to all executing processes, modern operating systems abstract memory addresses used by the systems virtual memory manager. This abstraction presents each process with the same memory address space, while allowing them to access different elements of memory in the VMM. This memory abstraction creates a range of available memory addresses that is referred to as an address space. The address space has a specific range of values and it is the limits of this range that restricts the amount of memory available to the executing process.

The range of an address space is defined by the native word size of the operating system. For Windows NT based systems, this value has a size of 32 bits, which corresponds to an address space of 2^32 bytes or approximately 4 gigabytes of memory. Thus, all processes on Windows NT platforms are limited to having access to only 4 gigabytes of memory (This limit will be expanded to a range of 2^64, with the introduction of Win64 platforms in the future).

This is not the only limitation placed on processes on Windows platforms though. System addresses are mapped into this address space, so the available address space is further reduced. The amount of address space is utilized by the system is dependent on the version of Windows NT being used. For Windows NT Workstation and some versions of Windows NT Server, the upper 2 gigabytes of the address space is reserved for the system. This leaves only 2 gigabytes available to the process for use. For Windows NT Server, Enterprise Edition only the upper 1 gigabyte of the address space is reserved for the system, leaving 3 gigabytes of address space available for use by the process. These limitations are summarized in the following table.

Operating System Available Address Space
Windows NT Workstation and Server 2 Gigabytes
Windows NT Server, Enterprise Edition 3 Gigabytes

Solution:
The only solution for this type of limitation is for the operating system to change. For Windows, a user could either purchase Windows NT Server, Enterprise Edition or wait for the release of 64-bit versions of Windows.

Memory Fragmentation

Issue:
Even when a sufficient amount of free memory is available and the memory request being made is below the limits set by the operation system, memory requests can fail. Often this results from memory fragmentation.

When memory is requested from the system a free space of the requested size must exist in the processes address space. If a free space in the address space doesn't exist, the request will fail, even if enough memory exists to meet the request. For small requests this situation hardly ever transpires, but the larger the request, the greater a chance this issue will occur. This scenario is exacerbated when memory fragmentation occurs.

Memory fragmentation takes place when a block of memory is allocated that divides a region of the processes address space, reducing the maximum size of a free block of memory. The following diagram demonstrates this issue.


While sometimes difficult to identify, an indication that memory fragmentation is taking places is when a request for a large block of memory fails, but smaller requests that total the larger request succeed.

Memory fragmentation is often the result of poor software implementation, arising when the following scenario takes place:

  • A large block of memory is allocated.
  • A smaller block of memory is allocated. This allocation places that memory above the large block of memory in the address space.
  • The large block of memory is released to the system.

This can occur often when working with large, dynamic memory blocks, so developers must be aware of the issue when designing and implementing software.

Solution:
The key to resolving this type of issue is to be aware that it exists during application development, allocating memory in a correct manner (small, persistent allocations first, followed by large, transient allocations).

Memory Allocation in IDL

The memory allocation system in IDL is very simplistic, leaving main memory accounting and management up to the operating system (malloc() and free()). For efficiency in some areas, IDL does utilize several special sub-systems and methodologies to manage internal memory. Of particular interest are the following:

Temporary Memory    This system is core to the interpreter and used for allocation of memory in a system routine that is called from the interpreter. When memory is allocated using this system, the interpreter will ensure that the memory is returned when the called routine returns. This prevents any memory leaks from occurring in system routines.

Allocating in Blocks    In subsystems that utilize a common record size and that are extensively used in IDL, a memory pool is used. This pool will allocated multiple records at a single time, reducing the overhead of multiple allocation events. Also, this system maintains a list of free records, so when elements are returned they are actually recycled.

This system is often used for small records, such as in the Widget system and the Pointer-Object heap system in IDL.

Central Allocation All memory in IDL is allocated and released through a central set of routines. These routines fulfill the memory request using the system memory allocation functions (malloc() and free()) and also keep count of the memory allocated by the system. This is what provides the information displayed by the "HELP, /MEMORY" IDL command.

Correct Development The IDL Engineering team makes extreme efforts to ensure that the proper memory allocation methodology and procedures are followed when implementing IDL functionality. Efficiency with respect to speed and memory usage is key to IDL's success and as such rigorously checked with every product release.

These systems improve efficiency of memory usage in IDL, but do nothing for overall memory allocation management. This task is left to the operating system since it is more efficient at this operation. As such, all of the aforementioned memory allocation issues can and will affect the memory available to the IDL user. Because of this, the IDL user should be aware of these issues and take appropriate actions as warranted.


If you have any additional questions or comments, please contact Rivix Technical Support for assistance.

Copyright (C) RIVIX, LLC. 1998-2021