Skip to content

Commit e3bc83a

Browse files
fix: dispose the text the charts lay out
A laid-out TextPainter holds a native paragraph and has to be disposed. None of them were, and a chart lays out a few dozen labels a frame: over eight thousand painters were left to the garbage collector across the test suite alone. TextPainterCache now disposes the painter it evicts, the ones clear() drops and everything it still holds when the new dispose() is called; all 39 charts that own a cache dispose it with their state. The depth chart was laying out every label afresh on every paint and throwing the painters away — it goes through a cache like every other chart. The painters that cannot be cached, because the cache keys on a plain string — a multi-span legend row, an axis label, a marker label, an event glyph in its own icon font — are disposed as soon as they are painted. KChartWidget also disposes the CurvedAnimation wrapping each scroll animation, rather than leaving one behind per fling. The suite runs under leak_tracker from here on, so a widget that leaves a disposable behind fails its file. The two ChangeNotifiers the caller owns, ChartDrawingController and KChartController, are left out of it: the chart attaches and detaches but never disposes what it did not make.
1 parent f079f21 commit e3bc83a

47 files changed

Lines changed: 264 additions & 18 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎lib/src/book/book_heatmap_chart.dart‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,13 @@ class BookHeatmapChart extends StatefulWidget {
455455

456456
class _BookHeatmapChartState extends State<BookHeatmapChart> {
457457
final TextPainterCache _text = TextPainterCache(capacity: 64);
458+
459+
@override
460+
void dispose() {
461+
_text.dispose();
462+
super.dispose();
463+
}
464+
458465
BookHeatmapLayout _layout = BookHeatmapLayout.empty;
459466
Offset? _pointer;
460467

‎lib/src/bubble/bubble_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ class _BubbleChartState extends State<BubbleChart>
397397

398398
@override
399399
void dispose() {
400+
_text.dispose();
400401
_animation.dispose();
401402
super.dispose();
402403
}

‎lib/src/bullet/bullet_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ class _BulletChartState extends State<BulletChart>
405405

406406
@override
407407
void dispose() {
408+
_text.dispose();
408409
_animation.dispose();
409410
super.dispose();
410411
}

‎lib/src/calendar/calendar_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ class _CalendarChartState extends State<CalendarChart>
545545

546546
@override
547547
void dispose() {
548+
_text.dispose();
548549
_animation.dispose();
549550
super.dispose();
550551
}

‎lib/src/chord/chord_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ class _ChordChartState extends State<ChordChart>
537537

538538
@override
539539
void dispose() {
540+
_text.dispose();
540541
_animation.dispose();
541542
super.dispose();
542543
}

‎lib/src/delta/cumulative_delta_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ class _CumulativeDeltaChartState extends State<CumulativeDeltaChart>
503503

504504
@override
505505
void dispose() {
506+
_text.dispose();
506507
_animation.dispose();
507508
super.dispose();
508509
}

‎lib/src/depth_chart.dart‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'depth_ratio_bar.dart';
66
import 'depth_style.dart';
77
import 'depth_translations.dart';
88
import 'entity/depth_entity.dart';
9+
import 'renderer/text_painter_cache.dart';
910
import 'renderer/depth_painter.dart';
1011

1112
/// A market-depth chart for one order book.
@@ -102,9 +103,16 @@ class DepthChart extends StatefulWidget {
102103
}
103104

104105
class _DepthChartState extends State<DepthChart> {
106+
final TextPainterCache _text = TextPainterCache(capacity: 64);
105107
Offset? pressOffset;
106108
bool isLongPress = false;
107109

110+
@override
111+
void dispose() {
112+
_text.dispose();
113+
super.dispose();
114+
}
115+
108116
@override
109117
Widget build(BuildContext context) {
110118
if (widget.mode == DepthChartMode.ladder) {
@@ -151,6 +159,7 @@ class _DepthChartState extends State<DepthChart> {
151159
widget.chartStyle,
152160
widget.offset,
153161
widget.chartTranslations,
162+
textCache: _text,
154163
mode: widget.mode,
155164
scale: widget.scale,
156165
zoom: widget.zoom,

‎lib/src/distribution/box_plot_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ class _BoxPlotChartState extends State<BoxPlotChart>
490490

491491
@override
492492
void dispose() {
493+
_text.dispose();
493494
_animation.dispose();
494495
super.dispose();
495496
}

‎lib/src/distribution/histogram_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ class _HistogramChartState extends State<HistogramChart>
367367

368368
@override
369369
void dispose() {
370+
_text.dispose();
370371
_animation.dispose();
371372
super.dispose();
372373
}

‎lib/src/dumbbell/dumbbell_chart.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ class _DumbbellChartState extends State<DumbbellChart>
426426

427427
@override
428428
void dispose() {
429+
_text.dispose();
429430
_animation.dispose();
430431
super.dispose();
431432
}

0 commit comments

Comments
 (0)