May 25th, 2025
Questo è il quarto e ultimo post del blog nella serie
Flutter – Rilevamento delle perdite di memoria
. Se non l’hai ancora fatto, ti suggerisco caldamente di iniziare con il
.
Il 1° settembre 2022, Polina Cherkasova ha effettuato il primo commit nel suo nuovo progetto Dart-lang chiamato
. Questo membro chiave del team Flutter ha ricevuto il compito di creare uno strumento che aiutasse a rilevare oggetti non eliminati e non raccolti dal garbage collector.
Il piano per questo strumento è di essere incluso in Dart DevTools una volta completato, ma al momento della scrittura di questo articolo, non è ancora stato rilasciato ufficialmente (le mie versioni attive:
Flutter 3.27.1
,
Dart 3.6.0
,
DevTools 2.40.2
). Poiché la documentazione è praticamente inesistente, ho dovuto esaminare il codice sorgente per capire come funziona e come qualcuno può utilizzarlo.
L’obiettivo di questo articolo è insegnarti come puoi usarlo.
L’idea del team Dart dietro questo pacchetto è semplice. Il pacchetto aiuta a identificare e diagnosticare le perdite di memoria nelle applicazioni Dart.
Caratteristiche principali:
Leggendo il codice, ho identificato alcuni punti in cui ho notato che i metodi di Leak Tracker vengono chiamati durante la creazione di oggetti che non si auto-eliminano. Se Leak Tracker viene istanziato, farà quanto segue:
Esempio di codice SDK Flutter - Tracciamento della creazione dell'oggetto ImageInfo
Esempio di codice SDK Flutter - Tracciamento della creazione dell'oggetto TrainHoppingAnimation
Esempio di codice SDK Flutter - Tracciamento della creazione dell'oggetto TextSelectionOverlay
Come puoi usare Dart Leak Tracker prima del rilascio ufficiale? La documentazione per la configurazione sul repository GitHub ufficiale è obsoleta e non funziona più. Correggendo un bug in Dart Leak Tracker (
non è ancora stata unita), mettendo insieme alcuni frammenti di codice da un post di Reddit di due anni fa e alcune questioni su GitHub, sono riuscito a farlo funzionare.
Per utilizzare Dart Leak Tracker all’interno della tua applicazione Flutter, devi prima correggere il bug nel codice di Dart Leak Tracker. Naviga fino a dove è installato il tuo pacchetto dart-lang sulla tua macchina e apri il file
pkgs/leak_tracker/lib/src/leak_tracking/_object_tracker.dart
. Devi correggere il filtro che filtra le perdite raccolte in ritardo dal garbage collector.
LeakType.gcedLate: _objects.gcedLateLeaks
// .where((record) => _leakFilter.shouldReport(LeakType.notGCed, record)) fixed
.where((record) => _leakFilter.shouldReport(LeakType.gcedLate, record))
.map((record) => record.toLeakReport())
.toList(),
});
Successivamente, se stai utilizzando il mio codice dal precedente post del blog della serie, sostituisci il contenuto del file
main.dart
con il contenuto trovato
. Se stai cercando perdite nella tua applicazione, assicurati di aggiungere quanto segue al tuo file
main.dart
(salta questi passaggi se stai utilizzando il mio codice):
Devi importare le dipendenze richieste e, prima che venga chiamato runApp, devi istanziare il pacchetto Leak Tracking.
import 'package:flutter/foundation.dart';
import "package:leak_tracker/leak_tracker.dart";
void main() {
LeakTracking.start();
FlutterMemoryAllocations.instance.addListener((ObjectEvent event) {
LeakTracking.dispatchObjectEvent(event.toMap());
});
runApp(const MyApp());
}
Devi implementare un meccanismo che raccolga le perdite attualmente osservate e te le restituisca. Nella mia applicazione demo, ho modificato la callback onPressed del
TextButton
in modo che raccolga anche le perdite.
onPressed: () async {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => const HomePage()));
await Future.delayed(const Duration(milliseconds: 500)); // let the leak_tracker settle
Leaks leaks = await LeakTracking.collectLeaks();
print("Leaks collected");
},
Esegui l’applicazione, fai cose che normalmente producono perdite di memoria e poi prova a raccoglierle. Il modo più veloce per osservare ciò che è stato raccolto è posizionare un punto di interruzione e verificare cosa è stato assegnato alla variabile
leaks
.
Tieni presente che il pacchetto
leak_tracker
non è ancora stato rilasciato e, proprio come con lo strumento Memory view, è possibile che non abbia trovato il colpevole delle tue perdite.
Perché leak_tracker non ha trovato le tue perdite?
Ora arriva la parte difficile. L’unica cosa che rimane è produrre e analizzare il dump di memoria della tua applicazione. L’analisi del dump di memoria è fuori dal campo di questa serie di post del blog, ma sarò felice di
con te.