Memory objects

Updated: April 19, 2023

A memory object is a container for physical memory.

We need to consider the following aspects:

Layout
The physical composition of the object: the physical memory pages that actually back the mapped memory. The pages might not yet exist; for example, if you've mapped a file, some of the pages might be in memory, and some might not have been loaded from the file. If you've allocated a contiguous object using shm_ctl(), the physical memory pages are in place. Nevertheless, all the pages form the layout of the object, and you can have more than one range of memory in an object.
Content
The data held by the object.

A memory object has a specific life cycle; the object has a creator (or owner) and a reference count that the kernel maintains. The reference count increases as the object is created, duplicated, connected to, or mapped. It decreases when connections are severed, the object is unmapped, and so on. When the reference count goes to zero, the kernel destroys the object.

Here are some examples:

Note: The direct mapping of physical addresses doesn't result in a memory object.

The main APIs for working with memory objects include the following:

shm_open()
Create a new shared memory object or open an existing one, based on a path under /dev/shmem.
posix_typed_mem_open()
Open a named memory pool that you can then allocate from.
shm_ctl()
A QNX Neutrino function that gives you fine control over the layout of an object that was opened with shm_open().
mmap()
Expose memory in the virtual address space.
ftruncate()
Expand or contract an object that was opened with shm_open(). This gives you pageable anonymous memory.