[Prestaties][P2] TextPainters in de meetfuncties worden nooit vrijgegeven — native geheugendruk bij veel tabellen #2632

Closed
opened 2026-10-28 16:31:48 +00:00 by brenno · 0 comments
Owner

Symptoom

Decks en documenten met veel tabellen bouwen bij bewerken geheugendruk op, met af en toe haperingen door garbage collection.

Oorzaak

De gedeelde tekstmeting maakt per meting een TextPainter en geeft hem nooit vrij:

  • measureTextHeight (lib/services/text_measurement.dart:18-38) en _painterFor (regel 87-103, gebruikt door measureTextWidth/measureTextWordWidth) roepen geen dispose() aan;
  • idem chart_preview_improvement.dart (4×), cockpit_painter_support.dart (2×), code_preview.dart, scene_painter.dart.

(timeline_fit.dart, scorecard_preview.dart en chart_preview_radar.dart doen het wél goed.)

Een TextPainter houdt een native ui.Paragraph vast; zonder dispose() komt dat geheugen pas vrij als de garbage collector de Dart-wrapper finaliseert. En het aantal is groot: de tabelinpassing (tableFitCellSize → tableBlockHeight, lib/services/table_layout_metrics.dart:280-363) meet elke cel bij elke stap van de lettergroottezoektocht, plus de woordbreedtes. Voor een tabel van 40×6 is dat in de orde van 1 500 paragrafen per inpassing, en dat per breedte (strook, preview, presentator, beamer) zodra de dia verandert.

Gemeten (debug, Apple Silicon): tableFit kost koud 0,7 / 2,6 / 5,0 ms voor 8 / 20 / 40 rijen per breedte. Dat is acceptabel; het punt is de native-geheugenstroom eromheen, niet de rekentijd.

Voorgestelde oplossing

  • try { … } finally { painter.dispose(); } in alle meetfuncties die alleen een getal teruggeven.
  • In tableBlockHeight per (tekst, celgrootte, breedte) de rijhoogte memoïseren binnen één tableFit-aanroep: tussen de zoekstappen verandert alleen de celgrootte, en veel cellen ("OK", "Hoog") zijn identiek.

Toets

Flutter's leak-tracking (leak_tracker in testWidgets) op een tabeldia-test: geen niet-vrijgegeven TextPainters.

Onderdeel van de prestatie- en stabiliteitsinspectie van 28-10-2026 (EPIC #2637).

## Symptoom Decks en documenten met veel tabellen bouwen bij bewerken geheugendruk op, met af en toe haperingen door garbage collection. ## Oorzaak De gedeelde tekstmeting maakt per meting een `TextPainter` en geeft hem nooit vrij: - `measureTextHeight` (`lib/services/text_measurement.dart:18-38`) en `_painterFor` (regel 87-103, gebruikt door `measureTextWidth`/`measureTextWordWidth`) roepen geen `dispose()` aan; - idem `chart_preview_improvement.dart` (4×), `cockpit_painter_support.dart` (2×), `code_preview.dart`, `scene_painter.dart`. (`timeline_fit.dart`, `scorecard_preview.dart` en `chart_preview_radar.dart` doen het wél goed.) Een `TextPainter` houdt een native `ui.Paragraph` vast; zonder `dispose()` komt dat geheugen pas vrij als de garbage collector de Dart-wrapper finaliseert. En het aantal is groot: de tabelinpassing (`tableFitCellSize` → `tableBlockHeight`, `lib/services/table_layout_metrics.dart:280-363`) meet **elke cel** bij elke stap van de lettergroottezoektocht, plus de woordbreedtes. Voor een tabel van 40×6 is dat in de orde van 1 500 paragrafen per inpassing, en dat per breedte (strook, preview, presentator, beamer) zodra de dia verandert. Gemeten (debug, Apple Silicon): `tableFit` kost koud 0,7 / 2,6 / 5,0 ms voor 8 / 20 / 40 rijen per breedte. Dat is acceptabel; het punt is de native-geheugenstroom eromheen, niet de rekentijd. ## Voorgestelde oplossing - `try { … } finally { painter.dispose(); }` in alle meetfuncties die alleen een getal teruggeven. - In `tableBlockHeight` per (tekst, celgrootte, breedte) de rijhoogte memoïseren binnen één `tableFit`-aanroep: tussen de zoekstappen verandert alleen de celgrootte, en veel cellen ("OK", "Hoog") zijn identiek. ## Toets Flutter's leak-tracking (`leak_tracker` in `testWidgets`) op een tabeldia-test: geen niet-vrijgegeven `TextPainter`s. Onderdeel van de prestatie- en stabiliteitsinspectie van 28-10-2026 (EPIC #2637).
brenno 2026-10-29 12:20:12 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#2632
No description provided.