This chapter helps you understand memory use on Palm OS®.
- Memory Architecture discusses how memory is structured on Palm OS. It examines the structure of the basic building blocks of Palm OS memory: heaps, chunks, and records.
- The Memory Manager discusses how to use the Palm OS Memory Manager in your applications.
IMPORTANT: Do not confuse the handheld's RAM with read/write memory on expansion cards, such as SD cards or Memory Stick media. You access expansion cards through a different API. See Chapter 3, "Virtual File Systems," for more information.
Memory Architecture
IMPORTANT: This section describes the current implementation of Palm OS memory architecture. This implementation may change as Palm OS evolves. Do not rely on implementation-specific information described here; instead, always use the API provided to manipulate memory.
The Palm OS divides the total available RAM store into two logical areas: dynamic heaps and the storage heaps. A process's dynamic heap is used as working space for temporary allocations, and is analogous to the RAM installed in a typical desktop system. RAM not reserved for dynamic use is designated for the storage heaps and is analogous to disk storage on a typical desktop system.
Because power is always applied to the memory system, the dynamic and storage heaps preserve their contents when the handheld is turned "off" (that is, when it is in low-power sleep mode). Storage heaps are preserved even when the handheld is explicitly reset (unless the user performs a hard reset, in which case the storage heaps are reinitialized).
The Dynamic Heaps
The dynamic heap provides memory for dynamic allocations. From this heap the system provides memory for dynamic data such as global variables, system dynamic allocations, application stacks, temporary memory allocations, and application dynamic allocations (such as those performed when the application calls malloc()
or MemHandleNew()
). Each process has an independent dynamic heap that is created and destroyed along with the process.
The entire amount of RAM reserved for the dynamic heaps is always dedicated to this use, regardless of whether it is actually used for allocations. The size of the dynamic area of RAM on a particular handheld varies according to the OS version running, the amount of physical RAM available, the requirements of pre-installed software such as the TCP/IP stack or IrDA stack, and any other licensee requirements.
The Storage Heaps
The remaining portion of RAM not dedicated to use by the dynamic heaps is configured as a set of storage heaps and is used to hold nonvolatile user data such as appointments, to do lists, memos, address lists, and so on. An application accesses a storage heap by calling Data Manager functions such as DmNewHandle()
. Storage heaps retain their contents through soft reset cycles.
The size of the storage heap available on a particular handheld varies according to the OS version that is running; the amount of physical RAM and ROM that is available; and the storage requirements of end-user application software such as the Address Book, Date Book, or third-party applications.
Note that you typically work with the storage heap by manipulating databases. See Chapter 2, "Palm OS Databases," for information on creating and accessing Palm OS databases.
Heap Details
A heap is a contiguous area of memory used to contain and manage one or more smaller chunks of memory. When applications work with memory (for instance, allocate, resize, or free) they usually work with chunks of memory. An application can specify whether to allocate a new chunk of memory in a dynamic heap or a storage heap. The Memory Manager and the Data Manager each manages their respective heaps, rearranging chunks as necessary to defragment the heaps and merge free space.
Heaps in the Palm OS environment are referenced through heap IDs. A heap ID is a unique 16-bit value that is used to identify a heap within the Palm OS address space. The three defined heaps IDs are:
Chunks
In the Palm OS environment, all data are stored in chunks. A chunk is an area of contiguous memory between 1 byte and slightly less 2^26 bytes in a storage heap, or 2^31 bytes in a dynamic heap.
Every memory chunk used to hold storage data (as opposed to memory chunks that store dynamic data) is a record in a database implemented by the Palm OS Data Manager.
Memory chunks can be movable or immovable. When working with a storage heap, applications need to store data in movable chunks whenever feasible, thereby allowing the operating system to move chunks as necessary to create contiguous free space in memory for allocation requests. In a dynamic heap, on the other hand, applications should use the standard C APIs for working with memory (malloc()
, free()
, and the like); the standard C APIs have no concept of movable chunks.
When an application requests an immovable chunk it receives a pointer to that chunk. The pointer is simply that chunk's address in memory. Because the chunk cannot move, its pointer remains valid for the chunk's lifetime; thus, the pointer can be passed "as is" to the caller that requested the allocation.
When an application requests a movable chunk, the operating system generates a pointer to that chunk, just as it did for the immovable chunk, but it does not return the pointer to the caller. Instead, it stores the pointer to the chunk, called the master chunk pointer, in a master pointer table that is used to track all of the movable chunks in the heap, and returns a reference to the master chunk pointer. This reference to the master chunk pointer is known as a handle. It is this handle that the operating system returns to the caller that requested the allocation of a movable chunk.
Using handles imposes a slight performance penalty over direct pointer access but permits the operating system to move chunks around in the heap without invalidating any chunk references that an application might have stored away. As long as an application uses handles to reference data, only the master pointer to a chunk needs to be updated when the chunk is moved during heap defragmentation.
An application typically locks a chunk handle for a short time while it has to read or manipulate the contents of the chunk. The process of locking a chunk tells the Memory or Data Manager to mark that data chunk as immobile; a pointer to the chunk is returned that your application can use to manipulate the chunk contents. When an application no longer needs the data chunk, it should unlock the handle immediately to keep heap fragmentation to a minimum.
Chunks maintain a lock count. A count of zero indicates that the chunk is movable. Every time you lock a chunk, its lock count is incremented. You can lock a chunk a maximum of 14 times before an error is returned. (Unmovable chunks hold the value 15 in the lock field.) Unlocking a chunk decrements the value of the lock field by 1. When the lock count is reduced to 0, the chunk is again free to be moved by the operating system.
IMPORTANT: Note that any handle is good only until the system is reset. When the system resets, it reinitializes all dynamic memory areas and relaunches applications. Therefore, you must not store a handle in a database.
Internally each chunk is located by means of a local ID. The local ID of immovable chunk is a pointer to the chunk; the local ID of movable chunk is equivalent to the chunk handle.
Owner ID
In previous versions of Palm OS, the operating system used an owner ID to associate that chunk with an application. Because the dynamic heap of the main UI application is always destroyed and recreated during an application switch, owner IDs of memory chunks don't make sense in Palm OS Cobalt. The Memory Manager APIs for managing owner IDs exist for compatibility reasons; setting the owner ID of a chunk doesn't make the chunk persistent across application switches as in previous versions of Palm OS.
The Memory Manager
The Palm OS Memory Manager is responsible for maintaining the location and size of every memory chunk in the dynamic heaps. It provides an API for allocating new chunks, disposing of chunks, resizing chunks, locking and unlocking chunks, and compacting heaps when they become fragmented.
IMPORTANT: In Palm OS Cobalt the Memory Manager APIs exist mainly for use by the Data Manager to manage storage heaps. Application developers should use the standard C library functions such as
malloc()
and free()
to manage dynamic memory.
Allocating and Freeing Memory Chunks
To allocate a movable chunk, call MemHandleNew()
and pass the desired chunk size. To free a memory chunk given its handle, call MemHandleFree()
. The Memory Manager provides similar functions that work with immovable chunks: MemPtrNew()
allocates a memory chunk and returns a pointer to it, while MemPtrFree()
frees a chunk given its pointer.
The size of a chunk can be obtained with either MemHandleSize()
or MemPtrSize()
, depending on whether you have the chunk's handle or a pointer to its data. To resize a movable chunk use MemHandleResize()
. When resizing immovable chunks MemPtrRealloc()
is recommended; although there is a function called MemPtrResize()
, it should only be relied upon when you are making the chunk smaller since it can't increase the size of an immovable chunk unless there is free space in the heap immediately following the chunk.
If you have a pointer to a locked, movable chunk, you can recover the handle by calling MemPtrRecoverHandle()
.
Manipulating Chunk Contents
Because you have a pointer to any immovable chunk you've allocated with MemPtrNew
, you can read or write that chunk's contents directly. Before you can read or write data to a movable chunk, however, you must call MemHandleLock()
to lock it and get a pointer to it. Then, when you no longer need direct access to the chunk's contents, call MemHandleUnlock()
. (Note that after a call to MemHandleUnlock
, the pointer your application was using to access the chunk's contents is no longer valid.)
The Memory Manager provides three utility functions that you can use when working with the contents of a chunk:
-
MemMove()
moves memory from one place to another. -
MemSet()
fills memory with a specific value. -
MemCmp()
compares two regions of memory.
Note that in Palm OS Cobalt, however, applications should normally use the standard C library functions such as memmove()
or memcpy()
, memset()
, and memcmp()
to manage dynamic memory.