Mistake on this page?
Report an issue in GitHub or email us

Runtime memory statistics

Arm Mbed OS provides various runtime statistics to help characterize resource usage. This allows easy identification of potential problems, such as a stack close to overflowing. The metrics currently supported are available for the heap and the stack.

Heap statistics

Heap statistics provide exact information about the number of bytes dynamically allocated by a program. It does not take into account heap fragmentation or allocation overhead. This allows allocation size reports to remain consistent, regardless of order of allocation (fragmentation) or allocation algorithm (overhead).

To enable heap stats from Mbed CLI:

  1. Add the command-line flag -DMBED_HEAP_STATS_ENABLED=1, for example mbed compile -DMBED_HEAP_STATS_ENABLED=1
  2. Use the function mbed_stats_heap_get() to take a snapshot of heap stats.

To enable heap stats using mbed_app.json:

  1. Add the following to mbed_app.json:

    {
        "macros": [
            "MBED_HEAP_STATS_ENABLED=1"
        ],
        ...
    }
    
  2. Use the function mbed_stats_heap_get() to take a snapshot of heap stats.

    Note: This function is available even when the heap stats are not enabled but always returns zero for all fields.

    mbed_stats_heap_get() returns a struct containing the following:

    Variable Description
    current_size Bytes allocated currently.
    max_size Max bytes allocated at a given time.
    total_size Cumulative sum of bytes ever allocated.
    reserved_size Current number of bytes allocated for the heap.
    alloc_cnt Current number of allocations.
    alloc_fail_cnt Number of failed allocations.
    overhead_size Overhead added to heap for stats.

Example heap statistics use cases

  • Getting worst case memory usage, max_size, to properly size MCU RAM.
  • Detecting program memory leaks by the current size allocated (current_size) or number of allocations in use (alloc_cnt).
  • Use alloc_fail_cnt to check if allocations have been failing, and if so, how many.

Example program using heap statistics

/*
 * Copyright (c) 2020 Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"
#include "mbed_stats.h"

int main(void)
{
    mbed_stats_heap_t heap_stats;

    printf("Starting heap stats example\r\n");
    mbed_stats_heap_get(&heap_stats);
    printf("Start; Current heap: %lu\n", heap_stats.current_size);
    printf("Start; Max heap size: %lu\n", heap_stats.max_size);

    printf("\nAllocating 1000 bytes\n");
    void *allocation = malloc(1000);

    mbed_stats_heap_get(&heap_stats);
    printf("Post-Alloc; Current heap: %lu\n", heap_stats.current_size);
    printf("Post-Alloc; Max heap size: %lu\n", heap_stats.max_size);

    free(allocation);
    printf("\nFreed 1000 bytes\n");

    mbed_stats_heap_get(&heap_stats);
    printf("Post-Free; Current heap: %lu\n", heap_stats.current_size);
    printf("Post-Free; Max heap size: %lu\n", heap_stats.max_size);
}

Side effects of enabling heap statistics

  • An additional 8 bytes of overhead for each memory allocation.
  • The function realloc never reuses the buffer it is resizing.
  • Memory allocation is slightly slower due to the added bookkeeping.

Stack statistics

Stack stats provide information on the allocated stack size of a thread and the worst case stack use. You can query any thread on the system for stack information.

To enable stack stats from the command-line, add the command-line flag -DMBED_STACK_STATS_ENABLED=1, for example mbed compile -DMBED_HEAP_STATS_ENABLED=1

Alternatively, to enable stack stats using mbed_app.json, add the following to mbed_app.json:

{
    "macros": [
        "MBED_STACK_STATS_ENABLED=1"
    ],
    ...
}

There are two functions you can use to access the stack stats:

  • mbed_stats_stack_get calculates combined stack informations for all threads.
  • mbed_stats_stack_get_each provides stack informations for each thread separately.

Note: These functions are available even when the stack stats are not enabled but always return zero for all fields.

Both of these functions return a struct containing the following:

Variable Description
thread_id Identifier for the thread that owns the stack or 0 if multiple threads.
max_size Maximum number of bytes used on the stack.
reserved_size Current number of bytes allocated for the stack.
stack_cnt Number of stacks stats accumulated in the structure.

Example stack statistics use cases

  • Using max_size to calibrate stack sizes for each thread.
  • Detecting which stack is close to overflowing.

Example program using stack statistics

/*
 * Copyright (c) 2020 Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"
#include "mbed_stats.h"

int main(void)
{
    printf("Starting stack stats example\r\n");

    int cnt = osThreadGetCount();
    mbed_stats_stack_t *stats = (mbed_stats_stack_t *) malloc(cnt * sizeof(mbed_stats_stack_t));

    if (stats) {
        cnt = mbed_stats_stack_get_each(stats, cnt);
        for (int i = 0; i < cnt; i++) {
            printf("Thread: 0x%lx, Stack size: %u, Max stack: %u\r\n",
                   stats[i].thread_id, stats[i].reserved_size, stats[i].max_size);
        }
        free(stats);
    }
}

Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.