@@ -6,97 +6,146 @@ ESPMemoryMonitor monitor;
66MemoryTag httpTag;
77
88void setup () {
9- Serial.begin (115200 );
9+ Serial.begin (115200 );
1010
11- MemoryMonitorConfig cfg;
12- cfg.sampleIntervalMs = 1000 ;
13- cfg.historySize = 30 ;
14- cfg.internal = {48 * 1024 , 32 * 1024 };
15- cfg.psram = {256 * 1024 , 160 * 1024 };
16- cfg.enablePerTaskStacks = true ;
17- cfg.enableFailedAllocEvents = true ;
18- cfg.enableScopes = true ;
19- cfg.maxScopesInHistory = 16 ;
20- cfg.windowStatsSize = 8 ;
21- cfg.enableTaskTracking = true ;
22- monitor.init (cfg);
11+ MemoryMonitorConfig cfg;
12+ cfg.sampleIntervalMs = 1000 ;
13+ cfg.historySize = 30 ;
14+ cfg.internal = {48 * 1024 , 32 * 1024 };
15+ cfg.psram = {256 * 1024 , 160 * 1024 };
16+ cfg.enablePerTaskStacks = true ;
17+ cfg.enableFailedAllocEvents = true ;
18+ cfg.enableScopes = true ;
19+ cfg.maxScopesInHistory = 16 ;
20+ cfg.windowStatsSize = 8 ;
21+ cfg.enableTaskTracking = true ;
22+ monitor.init (cfg);
2323
24- httpTag = monitor.registerTag (" http_server" );
25- monitor.setTagBudget (httpTag, {60 * 1024 , 80 * 1024 });
24+ httpTag = monitor.registerTag (" http_server" );
25+ monitor.setTagBudget (httpTag, {60 * 1024 , 80 * 1024 });
2626
27- monitor.onThreshold ([](const ThresholdEvent &evt) {
28- const char *region = evt.region == MemoryRegion::Psram ? " PSRAM" : " DRAM" ;
29- if (evt.state == ThresholdState::Critical) {
30- ESP_LOGE (" MEM" , " %s critical free=%u" , region, static_cast <unsigned >(evt.stats .freeBytes ));
31- } else if (evt.state == ThresholdState::Warn) {
32- ESP_LOGW (" MEM" , " %s warning free=%u" , region, static_cast <unsigned >(evt.stats .freeBytes ));
33- } else {
34- ESP_LOGI (" MEM" , " %s recovered free=%u" , region, static_cast <unsigned >(evt.stats .freeBytes ));
35- }
36- });
27+ monitor.onThreshold ([](const ThresholdEvent &evt) {
28+ const char *region = evt.region == MemoryRegion::Psram ? " PSRAM" : " DRAM" ;
29+ if (evt.state == ThresholdState::Critical) {
30+ ESP_LOGE (
31+ " MEM" ,
32+ " %s critical free=%u" ,
33+ region,
34+ static_cast <unsigned >(evt.stats .freeBytes )
35+ );
36+ } else if (evt.state == ThresholdState::Warn) {
37+ ESP_LOGW (
38+ " MEM" ,
39+ " %s warning free=%u" ,
40+ region,
41+ static_cast <unsigned >(evt.stats .freeBytes )
42+ );
43+ } else {
44+ ESP_LOGI (
45+ " MEM" ,
46+ " %s recovered free=%u" ,
47+ region,
48+ static_cast <unsigned >(evt.stats .freeBytes )
49+ );
50+ }
51+ });
3752
38- monitor.onSample ([](const MemorySnapshot &snapshot) {
39- for (const auto ®ion : snapshot.regions ) {
40- const char *regionName = region.region == MemoryRegion::Psram ? " PSRAM" : " DRAM" ;
41- ESP_LOGI (" MEM" , " %s free=%u min=%u frag=%.02f" , regionName,
42- static_cast <unsigned >(region.freeBytes ),
43- static_cast <unsigned >(region.minimumFreeBytes ),
44- region.fragmentation );
45- }
46- for (const auto &stack : snapshot.stacks ) {
47- ESP_LOGD (" STACK" , " %s water=%uB priority=%u state=%d" , stack.name .c_str (),
48- static_cast <unsigned >(stack.freeHighWaterBytes ), stack.priority , static_cast <int >(stack.state ));
49- }
50- });
53+ monitor.onSample ([](const MemorySnapshot &snapshot) {
54+ for (const auto ®ion : snapshot.regions ) {
55+ const char *regionName = region.region == MemoryRegion::Psram ? " PSRAM" : " DRAM" ;
56+ ESP_LOGI (
57+ " MEM" ,
58+ " %s free=%u min=%u frag=%.02f" ,
59+ regionName,
60+ static_cast <unsigned >(region.freeBytes ),
61+ static_cast <unsigned >(region.minimumFreeBytes ),
62+ region.fragmentation
63+ );
64+ }
65+ for (const auto &stack : snapshot.stacks ) {
66+ ESP_LOGD (
67+ " STACK" ,
68+ " %s water=%uB priority=%u state=%d" ,
69+ stack.name .c_str (),
70+ static_cast <unsigned >(stack.freeHighWaterBytes ),
71+ stack.priority ,
72+ static_cast <int >(stack.state )
73+ );
74+ }
75+ });
5176
52- monitor.onFailedAlloc ([](const FailedAllocEvent &evt) {
53- ESP_LOGE (" MEM" , " alloc failed size=%u caps=0x%08x from %s" , static_cast <unsigned >(evt.requestedBytes ), evt.caps , evt.functionName );
54- });
77+ monitor.onFailedAlloc ([](const FailedAllocEvent &evt) {
78+ ESP_LOGE (
79+ " MEM" ,
80+ " alloc failed size=%u caps=0x%08x from %s" ,
81+ static_cast <unsigned >(evt.requestedBytes ),
82+ evt.caps ,
83+ evt.functionName
84+ );
85+ });
5586
56- monitor.onScope ([](const ScopeStats &s) {
57- ESP_LOGI (" SCOPE" , " %s used %+d DRAM %+d PSRAM in %llu us" ,
58- s.name .c_str (),
59- static_cast <int >(s.deltaInternalBytes ),
60- static_cast <int >(s.deltaPsramBytes ),
61- static_cast <unsigned long long >(s.durationUs ));
62- });
87+ monitor.onScope ([](const ScopeStats &s) {
88+ ESP_LOGI (
89+ " SCOPE" ,
90+ " %s used %+d DRAM %+d PSRAM in %llu us" ,
91+ s.name .c_str (),
92+ static_cast <int >(s.deltaInternalBytes ),
93+ static_cast <int >(s.deltaPsramBytes ),
94+ static_cast <unsigned long long >(s.durationUs )
95+ );
96+ });
6397
64- monitor.onTagThreshold ([](const TagThresholdEvent &evt) {
65- ESP_LOGW (" TAG" , " %s now %s at %u bytes" ,
66- evt.usage .name .c_str (),
67- evt.usage .state == ThresholdState::Critical ? " CRITICAL" :
68- evt.usage .state == ThresholdState::Warn ? " WARN" : " OK" ,
69- static_cast <unsigned >(evt.usage .totalInternalBytes + evt.usage .totalPsramBytes ));
70- });
98+ monitor.onTagThreshold ([](const TagThresholdEvent &evt) {
99+ ESP_LOGW (
100+ " TAG" ,
101+ " %s now %s at %u bytes" ,
102+ evt.usage .name .c_str (),
103+ evt.usage .state == ThresholdState::Critical ? " CRITICAL"
104+ : evt.usage .state == ThresholdState::Warn ? " WARN"
105+ : " OK" ,
106+ static_cast <unsigned >(evt.usage .totalInternalBytes + evt.usage .totalPsramBytes )
107+ );
108+ });
71109
72- monitor.onTaskStackThreshold ([](const TaskStackEvent &evt) {
73- if (evt.appeared ) {
74- ESP_LOGI (" TASK" , " task created: %s" , evt.usage .name .c_str ());
75- } else if (evt.disappeared ) {
76- ESP_LOGW (" TASK" , " task disappeared: %s" , evt.usage .name .c_str ());
77- } else {
78- ESP_LOGW (" TASK" , " task %s stack %s (%uB headroom)" , evt.usage .name .c_str (),
79- evt.state == StackState::Critical ? " CRITICAL" :
80- evt.state == StackState::Warn ? " WARN" : " SAFE" ,
81- static_cast <unsigned >(evt.usage .freeHighWaterBytes ));
82- }
83- });
110+ monitor.onTaskStackThreshold ([](const TaskStackEvent &evt) {
111+ if (evt.appeared ) {
112+ ESP_LOGI (" TASK" , " task created: %s" , evt.usage .name .c_str ());
113+ } else if (evt.disappeared ) {
114+ ESP_LOGW (" TASK" , " task disappeared: %s" , evt.usage .name .c_str ());
115+ } else {
116+ ESP_LOGW (
117+ " TASK" ,
118+ " task %s stack %s (%uB headroom)" ,
119+ evt.usage .name .c_str (),
120+ evt.state == StackState::Critical ? " CRITICAL"
121+ : evt.state == StackState::Warn ? " WARN"
122+ : " SAFE" ,
123+ static_cast <unsigned >(evt.usage .freeHighWaterBytes )
124+ );
125+ }
126+ });
84127
85- monitor.onLeakCheck ([](const LeakCheckResult &res) {
86- for (const auto &d : res.deltas ) {
87- const char *regionName = d.region == MemoryRegion::Psram ? " PSRAM" : " DRAM" ;
88- ESP_LOGI (" LEAK" , " %s drift %+0.1fB frag %+0.2f" , regionName, d.deltaFreeBytes , d.deltaFragmentation );
89- }
90- });
128+ monitor.onLeakCheck ([](const LeakCheckResult &res) {
129+ for (const auto &d : res.deltas ) {
130+ const char *regionName = d.region == MemoryRegion::Psram ? " PSRAM" : " DRAM" ;
131+ ESP_LOGI (
132+ " LEAK" ,
133+ " %s drift %+0.1fB frag %+0.2f" ,
134+ regionName,
135+ d.deltaFreeBytes ,
136+ d.deltaFragmentation
137+ );
138+ }
139+ });
91140}
92141
93142void loop () {
94- auto scope = monitor.beginScope (" http_req" , httpTag);
95- delay (1000 );
96- scope.end ();
143+ auto scope = monitor.beginScope (" http_req" , httpTag);
144+ delay (1000 );
145+ scope.end ();
97146
98- static uint32_t counter = 0 ;
99- if (++counter % 60 == 0 ) {
100- monitor.markLeakCheckPoint (" steady_state" );
101- }
147+ static uint32_t counter = 0 ;
148+ if (++counter % 60 == 0 ) {
149+ monitor.markLeakCheckPoint (" steady_state" );
150+ }
102151}
0 commit comments