You can accomplish many programming tasks in VOS and OpenVOS without knowing the details of how the operating system manages the user address space. But it is fun to know the details, and sometimes to accomplish a task you need to adjust the default configuration. This post is an introduction to the VOS user address space.
The VOS user address space is divided into 5 areas, each of which is used for a specific purpose. In order, from the lowest address (@0x) to the highest address (@7FFFFFFFx) they are the program module area, the dynamically-allocated shared virtual memory area, the user heap, the user stack, and a small area reserved for use by the operating system itself. The following diagram shows the order of these areas. It is not to scale. This diagram is specific to the V Series implementation (VOS Release 15.0 and higher).
Program Module |
Shared Virtual Memory |
User Heap |
(dead zone) |
User Stack |
System Data |
The size of the program module area is fixed at 128 MB. The size of the system data area is fixed at just under 2 MB. The sizes of the other 3 areas can be adjusted to satisfy the needs of the running program. The default size of the shared virtual memory area is 896 MB. Thus, the first two areas occupy 1 gigabyte or half of the address space. The default size of the user heap varies somewhat by the version of VOS or OpenVOS. In Release 17.0, the default size is 64MB. The default size of the user stack is 8MB. The unused space between the heap and the stack is called the dead zone. Because the heap grows up (low addresses to high addresses) and the stack grows down (high to low), the dead zone can be claimed by either the heap or stack for expansion. The total amount of virtual memory available to the heap, stack, and system data is another 1 gigabyte. All total, a user process has access to 2 gigabytes of virtual memory.
The total amount of heap space that can be used is subject to an administrative limit. The same is true for the stack space, and for the total amount of space (which is the sum of the program module space, shared virtual memory space, heap space, and stack space). The module-wide limits are viewed using the list_default_cmd_limits command, and modified using the update_default_cmd_limits command. New processes inherit these module-wide values. After the process is up and running, their limits can be viewed using the list_process_cmd_limits command and modified using the update_process_cmd_limits command.
The process-wide limit values are then used to initialize the limits used each time that a program is executed. Once a program is up and running, it can call the s$get_current_cmd_limits and s$set_current_cmd_limits subroutines to retrieve or modify the limits for the duration of its execution. In this way, a program can reserve more space for its stack than the system’s initial default value, or can increase the amount of heap space that is is allowed to use. Conversely, if it is concerned about using too much space, perhaps due to a coding error, it can also decrease the amount of space that it can use.
For more information, read the description of the update_default_cmd_limits and bind commands.