Basic Memory Allocation

A Visual Guide for Memory Map and Allocation

Application Memory Map

The Cafe Core OS (COS) uses the memory map shown in the Figure 1. Application code and data are placed in MEM2, or main memory. The production version of an application is allocated 1 GB of main memory.


Figure 1: Product Memory Map

On a CAT-DEV, the development version of an application is allocated 2 GB of main memory, as shown in Figure 2.


Figure 2: Devkit Memory Map

Memory Areas

The system reserves all of the memory, except for the areas allocated to your application. The system-reserved memory is not available to your application.

Application Code and Data

Your application's code and data areas reside in MEM2, or main memory.

MEM1

MEM1 is a dedicated 32 MB of fast memory that is reserved for graphics rendering or other high-use textures (render targets, depth buffers, auxiliary buffers). You should profile your application with various resources stored in MEM1 to determine the best performance.

An application can access MEM1 only when the application is running in the foreground.

You may not use MEM1 for resources that have lifetimes longer than your foreground state. For example, OSDynLoad_SetAllocator, OS data structures such as OSThread, and calls to File System and other I/O functions may not target the foreground bucket or MEM1.

For more information, see Foreground Resources and OSGetMemBound.

NOTE:
To simplify the demos, the demo library uses an expanded heap to manage MEM1. The more efficient way is to use the frame heap directly. For more information on using the frame heap, see The Frame Heap Manager.

Foreground Bucket

The foreground bucket is an extra 40 MB area in the foreground area of MEM2, above and beyond the 1 GB that is reserved for your application's code and data. This memory is available to an application only when it is running in the foreground.

You should use this only for graphics scan buffers and other data that:

  1. is only needed when your application is in the foreground;
  2. can be quickly discarded when switching to the background; and
  3. can be set up or regenerated quickly when switching back to the foreground.

Similar to MEM1, you may not use the foreground bucket for resources that have lifetimes longer than your foreground state.

For more information, see Foreground Resources and OSGetForegroundBucketFreeArea.

Although the ProcUISetBucketStorage function can be used to save and restore the foreground bucket over a transition to the background and back, doing so effectively defeats any advantages of using the foreground bucket.

Graphics Tiling Aperture

The GPU has the ability to remap CPU accesses to a given texture or render target such that a tiled surface appears with its pixels in linear order in memory. This is known as the graphics tiling aperture feature. When the relevant GX2 API is called, the address returned will be in the graphics tiling aperture memory range. No actual memory exists here; it just points back to another area of user graphics memory space (in MEM1 or MEM2).

Memory Access

An application uses cache to access memory as shown in Figure 3. Cached and uncached access were both available to Wii applications. Only cached memory access is available to Wii U applications.


Figure 3: Cached Memory Access

Memory Allocation

Mem Library

The MEM Library is the memory management library provided in Cafe SDK. It supports three types of heaps: expanded heap, frame heap, and unit heap. Under Operating System in the Cafe API Function Reference Manual, there is a Mem category, in which the algorithm and APIs for each heap type are described.

Differences from Wii

The Wii SDK had two types of memory management functions: OSAlloc and the MEM Library. For Cafe, use of OSAlloc, which was retained for Nintendo GameCube compatibility, is discontinued, and the MEM Library is the only remaining type of memory management function. Also, in Wii, the memory area that remains after loading an application was called arena. For Cafe, the arena is integrated into the MEM Library and provided as a base heap.

Base Heap

One big heap that is created from the memory area available to the application is referred to as a 'base heap'. MEM1, MEM2, and the foreground area (FG) have their own base heaps, which are initialized when an application starts up.

The MEM1 base heap is the frame heap of the MEM Library; the MEM2 base heap is an expanded heap; the FG base heap is also a frame heap. However, it is recommended that MEM1 be used as the storage location for GPU render targets and that the FG area be used as the storage location for scan buffers.

Memory Allocation Using a Default Allocator

Management of a base heap can be accomplished by using a default allocator (MEMAllocFromDefaultHeap), or can be overridden with another heap management mechanism, if the application specifies it. The default allocator allocates memory from the default heap. By default, the default heap is the base heap of MEM2. The default heap implementation uses the MEM_HEAP_OPT_THREAD_SAFE flag to assure that it is thread-safe.

Both malloc and new allocate memory from the heap for Green Hills standard library. The standard library obtains memory from the default heap to create its own heap. If malloc or new attempt to allocate memory larger than the free space in the malloc heap, the library will obtain additional memory from the default heap to enlarge its heap.

NOTE:
The default heap that is used by malloc is created before an application begins and is not deleted until the application exits. The default heap survives for the rest of the applications lifetime. For information on customizing the default heap, see Customize Memory Management.

Memory Management

The default allocator is a convenient function available to applications without initialization. Complex applications may require more flexible memory management.

Typical memory management methods include:

Memory Required for SDK Libraries

Usage by Library

Some SDK libraries allocate memory from the default heap. The tables below summarizes their usage.

Default Heap Usage in the SDK
Library Amount
OS Loader Depends on the size of the requested RPL. See OSDynLoad_SetAllocator. You can supply an alternate memory allocator.
Audio (AX) Depends on the specific effect requested; see the AX Effects Memory Usage table. You can supply an alternate memory allocator.
USB_MIC 100 KB per microphone or headset, up to a maximum of 2 devices, for a total of 200 KB.
GX2
  • GX2Init: If GX2_INIT_ATTRIB_CB_BASE is not set, GX2 allocates 4 MB from the default heap.
  • GX2RCreate: Size varies depending on user settings.
In both cases, you can supply an alternate memory allocator.
GFD Depends on the specific request. Source code is available for this optional library, and you can supply an alternate memory allocator.
Matrix (MAT) Depends on the specific request. Source code is available for this optional library, and you can supply an alternate memory allocator.
ProcUI 24 KB on initialization + 112 bytes per registered callback. You can supply an alternate memory allocator; see ProcUISetMemoryPool for details.
Network DNS 6144 bytes per request up to a max of 190,464 bytes. You can supply an alternate memory allocator; see SOResolverRegisterAllocator for details.
HTTP Client Depends on the specific request. You can supply an alternate memory allocator; see Memory Management in the HTTP Client Library for details.
Standard C library from Green Hills Software Depends on the specific request.
C++ Runtime Library from Green Hills Software Depends on the specific request.
zlib Depends on the specific operation requested; see its zalloc function.

Memory allocation requirements for AX effects vary depending on the effect. By default, the required memory is allocated from the default heap. See AXFX2SetHooks if you wish to supply a different allocator. The table below lists AX effects and their memory requirements.

AX Effects Memory Usage
Effect Bytes (/KB)
sound-1 sound-2
32KHz 32KHz 48KHz
Chorus 2ch 25 25 37
Chorus 4ch 51 50 75
Chorus 6ch 77 63 94
Compressor 2ch N/A 0.1 0.1
Compressor 4ch N/A 0.1 0.1
Compressor 6ch N/A 0.1 0.1
Delay 2ch 512 [26 ~ 256] [39 ~ 384]
Delay 4ch 1024 [52 ~ 512] [78 ~ 768]
Delay 6ch 1536 [78 ~ 768] [117 ~ 1152]
Flanger 2ch N/A 4 6
Flanger 4ch N/A 7 11
Flanger 6ch N/A 9 14
Overdrive 2ch N/A 0.1 0.1
Overdrive 4ch N/A 0.1 0.1
Overdrive 6ch N/A 0.1 0.1
PitchShift 2Ch N/A 13 19
PitchShift 4Ch N/A 26 39
PitchShift 6Ch N/A 39 57
Reverb 2ch 98 79 118
Reverb 4ch 136 79 118
Reverb 6ch 137 79 119
ReverbI3dl2 2ch N/A 134 200
ReverbI3dl2 4ch N/A 134 200
ReverbI3dl2 6ch N/A 135 201

Usage Considerations

All of these allocations are dependent on an explicit call of an SDK API function, except for thread-local variables defined using the __thread storage specifier and C++ exceptions.

Most memory usage by API functions is repeatable; for example:

However, a few cases are not readily predicted; for example:

You should also review the documentation that comes with any additional SDK patches that you have received from your local Nintendo support organization. These packages describe any additional sources of memory allocation.

You should leave 1 MB free in the default heap beyond the application's maximum usage to deal with these unpredictable memory allocation effects in the SDK. You should monitor and measure your application's maximum usage as it runs and add in any additional margin (on top of the already mentioned 1 MB) to account for any application variability.

Demos

How to Allocate All of Memory

The following demo shows how to allocate all areas in the default heap and how an allocated area can be used for another heap:

$CAFE_ROOT/system/src/demo/os/memory/alloc_all_memory.c

How to Allocate Memory Using the Build-In Memory Allocator

The following demo shows how to allocate memory from the default heap. Memory can be allocated without initialization. The default heap is an expanded heap.

$CAFE_ROOT/system/src/demo/os/memory/alloc_memory.c

How to Measure Memory Allocation Performance

The following demo measures the memory allocation performance:

$CAFE_ROOT/system/src/demo/os/memory/memory_performance.c

Memory is allocated for three types of heaps and in various sizes to indicate the difference.


See Also

Memory Allocation and RPL Usage

Revision History

2014/03/04 Added info on default heap.
2014/02/28 Changed MEMInitDefaultHeap to sMEMInitDefaultHeap.
2014/02/06 Added Note for memalloc.
2013/12/05 ProcUI now supports a user-provided allocator.
2013/05/08 Automated cleanup pass.
2013/03/20 Converted to HTML.


CONFIDENTIAL