[MEM] Heap-allocate createDiscovery JsonDocuments (#2302)

createDiscovery sits at the bottom of the discovery call chain
(loop → launchBTDiscovery → <device>Discovery → createDiscoveryFromList
(9-col, VLA) → createDiscoveryFromList(13-col) → here). Keeping
2×1024 B StaticJsonDocuments on the stack burned loopTask headroom
down to ~100 B free under a full BLE + WebUI load. Moving the two
buffers to the heap drops that 2 KB off the stack peak.

Measured over the full test_perf + test_webui suite on
esp32dev-ble-hil-fastsys (dev HEAD):

  freestck_min_bytes: 292 → 2324 B   (+2032, target was ≥1500)
  minmem_soak_bytes: 18200 → 20652 B (+2452)
  all 17 tests still pass

The docs are function-scoped, so net heap usage is unchanged long-term
(free-on-return), and the soak heap floor actually improved.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
FlorianandClaude Opus 4.7 authored and GitHub committed 2026-04-25 12:00:13 -05:00
1 parent 9e8098964c
commit 23fc99f0fe
1 file changed
+8 -2
+8 -2
View File
@@ -451,7 +451,13 @@ void createDiscovery(const char* sensor_type,
const char* device_name, const char* device_manufacturer, const char* device_model, const char* device_id, bool retainCmd,
const char* state_class, const char* state_off, const char* state_on, const char* enum_options,
const char* command_template, bool diagnostic_entity) {
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
// Heap-allocate the two JsonDocuments: createDiscovery sits at the bottom of
// a deep call chain (loop → launchBTDiscovery → <device>Discovery →
// createDiscoveryFromList(9-col, VLA) → createDiscoveryFromList(13-col) →
// here). Keeping 2×1024 B on the stack burned loopTask's stack headroom
// down to ~100 B free under full perf load. Heap-backed docs drop that
// 2 KB off the peak.
DynamicJsonDocument jsonBuffer(JSON_MSG_BUFFER);
JsonObject sensor = jsonBuffer.to<JsonObject>();
// If a component cannot render it's state (f.i. KAKU relays) no state topic
@@ -608,7 +614,7 @@ void createDiscovery(const char* sensor_type,
sensor["ops"] = enum_options; // options
}
StaticJsonDocument<JSON_MSG_BUFFER> jsonDeviceBuffer;
DynamicJsonDocument jsonDeviceBuffer(JSON_MSG_BUFFER);
JsonObject device = jsonDeviceBuffer.to<JsonObject>();
JsonArray identifiers = device.createNestedArray("ids");