使用ESP32時如果懷疑存在內(nèi)存泄漏,第一步是找出程序的哪個部分正在泄漏內(nèi)存。使用xPortGetFreeHeapSize()、heap_caps_get_free_size()或相關(guān)函數(shù)來跟蹤應(yīng)用程序生命周期內(nèi)的內(nèi)存使用情況。嘗試將泄漏縮小到單個函數(shù)或函數(shù)序列,在這些函數(shù)中,可用內(nèi)存總是減少并且永遠不會恢復(fù)。
一旦確定了正在泄漏的代碼:
·在項目配置菜單中,導(dǎo)航到Component settings -> Heap Memory Debugging -> Heap tracing,選擇Standalone選項。
·在程序運行前調(diào)用heap_trace_init_standalone() 注冊一個可用于記錄內(nèi)存跟蹤的緩沖區(qū)。
·調(diào)用 heap_trace_start()開始記錄系統(tǒng)中的所有malloc/free。在你懷疑正在泄漏內(nèi)存的代碼段之前立即調(diào)用此方法。
·調(diào)用heap_trace_stop()在懷疑代碼段完成執(zhí)行后停止跟蹤。
·調(diào)用 heap_trace_dump()轉(zhuǎn)儲堆跟蹤的結(jié)果。
示例代碼:
#include "esp_heap_trace.h"
#define NUM_RECORDS 100
static heap_trace_record_t trace_record[NUM_RECORDS]; // This buffer must be in internal RAM
...
void app_main()
{
...
ESP_ERROR_CHECK( heap_trace_init_standalone(trace_record, NUM_RECORDS) );
...
}
void some_function()
{
ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
do_something_you_suspect_is_leaking();
ESP_ERROR_CHECK( heap_trace_stop() );
heap_trace_dump();
...
}
堆跟蹤的輸出大概這樣:
2 allocations trace (100 entry buffer)
32 bytes (@ 0x3ffaf214) allocated CPU 0 ccount 0x2e9b7384 caller 0x400d276d:0x400d27c1
0x400d276d: leak_some_memory at /path/to/idf/examples/get-started/blink/main/./blink.c:27
0x400d27c1: blink_task at /path/to/idf/examples/get-started/blink/main/./blink.c:52
8 bytes (@ 0x3ffaf804) allocated CPU 0 ccount 0x2e9b79c0 caller 0x400d2776:0x400d27c1
0x400d2776: leak_some_memory at /path/to/idf/examples/get-started/blink/main/./blink.c:29
0x400d27c1: blink_task at /path/to/idf/examples/get-started/blink/main/./blink.c:52
40 bytes 'leaked' in trace (2 allocations)
total allocations 2 total frees 0
上面的示例輸出是使用IDF監(jiān)視器自動解碼PC地址到它們的源文件和行號。
第一行表示與緩沖區(qū)的總大小相比,緩沖區(qū)中有多少分配項。
在HEAP_TRACE_LEAKS模式下,對于每個尚未釋放的跟蹤內(nèi)存分配,打印一行:
XXbytes
為已分配的字節(jié)數(shù)@0x...
是從malloc/calloc返回的堆地址。Internal
或PSRAM
是分配內(nèi)存的一般位置。CPUx
CPU x是分配時正在運行的CPU(0或1)。ccount0x...
是分配模式時的CCOUNT (CPU周期計數(shù))寄存器值。不同于CPU 0和CPU 1。caller0x...
給出調(diào)用malloc()/free()的調(diào)用堆棧,作為PC地址列表??梢詫⑺鼈兘獯a為源文件和行號。
可以在項目配置菜單中Heap Memory Debugging -> Enable heap tracing -> Heap tracing stack depth配置為每個跟蹤項記錄的調(diào)用堆棧的深度。每個分配最多可以記錄10個堆棧幀(默認(rèn)為2個)。每增加一個堆棧幀,每個heap_trace_record_t記錄的內(nèi)存使用都會增加8個字節(jié)。
最后,打印內(nèi)存泄漏字節(jié)的總數(shù)(在運行跟蹤時已分配但未釋放的字節(jié)),以及它所表示的總分配數(shù)。如果跟蹤緩沖區(qū)的大小不足以容納發(fā)生的所有分配,則將打印警告。如果看到此警告,應(yīng)該縮短跟蹤周期或增加跟蹤緩沖區(qū)中的記錄數(shù)量。
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4379瀏覽量
64785 -
內(nèi)存泄漏
+關(guān)注
關(guān)注
0文章
40瀏覽量
9388 -
ESP32
+關(guān)注
關(guān)注
21文章
1015瀏覽量
19209
發(fā)布評論請先 登錄
使用ESP32實現(xiàn)藍牙通信
ESP32硬件設(shè)計指南
ESP32硬件設(shè)計指南

ESP32模組的主要特性
ESP32開發(fā)套件 ESP32-DevKitC
ESP32-WROOM-32E和ESP32-WROOM-32UE模組的區(qū)別

esp32和arduino的區(qū)別,esp32能否替代arduino
ESP32-C6的特性介紹
ESP32 開發(fā)之旅② Arduino For ESP32說明

ESP32 SDIO 使用教程

ESP32系列芯片的規(guī)格
ESP32到ESP32通過Internet進行通信

評論