Skip to content

[cloud_firestore]: Very Slow App Performance - Waiting for a blocking GC Alloc - Android Only #17805

@jijo0465

Description

@jijo0465

Is there an existing issue for this?

  • I have searched the existing issues.

Which plugins are affected?

No response

Which platforms are affected?

Android

Description

My application in production has suddenly started becoming very slow. I am using Firebase streams to load various lists from Firestore. The problem occurs only in Android. I tried replacing the streams with normal firestore db fetch with limits but still the issue persists. Its taking a very long time to fetch the data.

Reproducing the issue


class TrainerRepositoryImpl extends TrainerRepository {
  final AuthService _authService = Get.find();

  @override
  Future<Trainer?> getTrainer(String userId) async {
    // QuerySnapshot snapshot =
    // await collectionReference.where("id", isEqualTo: userId).get();
    return (await collectionReference.doc(userId).get()).data();
    // if (snapshot.docs.isNotEmpty)
    //   return snapshot.docs.first.data() as Rider;
    // else
    //   return null;
  }

  @override
  Future<Trainer?> addTrainer(Trainer trainer) async {
    try {
      await collectionReference.doc(trainer.id).set(trainer);
    } catch (e) {
      return null;
    }
    return await getTrainer(trainer.id);
  }

  @override
  Future<bool> exists(String userId) async {
    QuerySnapshot snapshot =
        await collectionReference.where("id", isEqualTo: userId).get();
    if (snapshot.docs.isNotEmpty) {
      return true;
    } else {
      return false;
    }
  }

  @override
  Future<Trainer?> updateTrainer(Trainer trainer) async {
    Trainer? t;
    // User? user = _authService.currentUser;
    await collectionReference
        .doc(trainer.id)
        .set(trainer, SetOptions(merge: true))
        .then((value) async {
      t = await getTrainer(trainer.id);
      if (kDebugMode) {
        print('Trainer Repository : Trainer Successfully updated');
      }
    }).onError((error, stackTrace) {
      if (kDebugMode) {
        print(error);
      }
      throw DataWriteException();
    });
    return t;
  }

  @override
  Stream<Trainer> get trainerStream {
    StreamController<Trainer> streamController = StreamController.broadcast();
    Stream<Trainer> stream = streamController.stream;
    collectionReference
        .doc(_authService.currentUser?.uid)
        .snapshots()
        .listen((event) {
      Trainer? t = event.data();
      if (t != null) {
        streamController.add(t);
      }
    });
    return stream;
  }

  @override
  Future<String> uploadProfilePic(File file) async {
    if (kDebugMode) {
      print('Uploading profile pic');
    }
    var ref =
        storageReference.child('profile_pic.${file.path.split('.').last}');
    if (kDebugMode) {
      print(storageReference.fullPath);
    }
    String url = '';
    try {
      await ref.putFile(file).then((p0) async {
        url = await ref.getDownloadURL();
        if (kDebugMode) {
          print(url);
        }
      });
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
      throw FileUploadException();
    }
    return url;
  }

  @override
  Future<String> uploadDriversLicence(File file) async {
    if (kDebugMode) {
      print('Uploading Drivers License');
    }
    var ref =
        storageReference.child("/drivers_license/${file.path.split('/').last}");
    String url = '';
    try {
      await ref.putFile(file).then((p0) async {
        url = await ref.getDownloadURL();
      });
    } catch (e) {
      throw DataWriteException();
    }
    return url;
  }

  @override
  Future<void> updateFirebaseMessagingDeviceToken(String token) async {
    try {
      await collectionReference.doc(_authService.currentUser?.uid).update({
        "notificationConfig": {
          'deviceTokens': [token],
          'createdAt': FieldValue.serverTimestamp(), // optional
          'platform': Platform.operatingSystem // optional
        }
      });
    } catch (e) {
      throw DatabaseException();
    }
  }

  @override
  Future<void> removeFirebaseMessagingDeviceToken(String? token) async {
    try {
      await collectionReference.doc(_authService.currentUser?.uid).update({
        "notificationConfig": {
          'deviceTokens': FieldValue.arrayRemove([token]),
          'createdAt': FieldValue.serverTimestamp(), // optional
          'platform': Platform.operatingSystem // optional
        }
      });
    } catch (e) {
      throw DatabaseException();
    }
  }

  @override
  Future<void> deleterTrainer(Trainer trainer) async {
    await collectionReference.doc(trainer.id).delete();
  }
}

Firebase Core version

3.5.0

Flutter Version

3.56.6

Relevant Log Output

W/WindowOnBackDispatcher(23991): OnBackInvokedCallback is not enabled for the application.
W/WindowOnBackDispatcher(23991): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
I/s.iturn.trainer(23991): Background young concurrent copying GC freed 55MB AllocSpace bytes, 6(26MB) LOS objects, 27% free, 165MB/229MB, paused 927us,283us total 251.112ms
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Background concurrent copying GC freed 133MB AllocSpace bytes, 18(31MB) LOS objects, 51% free, 90MB/186MB, paused 48us,38us total 436.682ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 161.600ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 161.770ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 162.094ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 160.523ms
I/s.iturn.trainer(23991): Background young concurrent copying GC freed 65MB AllocSpace bytes, 9(5096KB) LOS objects, 37% free, 116MB/186MB, paused 44us,44us total 102.625ms
I/s.iturn.trainer(23991): Background young concurrent copying GC freed 33MB AllocSpace bytes, 2(1440KB) LOS objects, 18% free, 152MB/186MB, paused 74us,40us total 141.753ms
I/s.iturn.trainer(23991): Background concurrent copying GC freed 33MB AllocSpace bytes, 9(6420KB) LOS objects, 39% free, 148MB/244MB, paused 108us,762us total 324.988ms
I/s.iturn.trainer(23991): Background young concurrent copying GC freed 46MB AllocSpace bytes, 0(0B) LOS objects, 17% free, 201MB/244MB, paused 49us,37us total 194.286ms
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Clamp target GC heap from 308MB to 256MB
I/s.iturn.trainer(23991): Background concurrent copying GC freed 21MB AllocSpace bytes, 34(22MB) LOS objects, 17% free, 212MB/256MB, paused 48us,34us total 452.134ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 415.454ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 414.003ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 171.398ms
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 96.351ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 96.755ms
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Clamp target GC heap from 343MB to 256MB
I/s.iturn.trainer(23991): Background concurrent copying GC freed 9058KB AllocSpace bytes, 0(0B) LOS objects, 3% free, 247MB/256MB, paused 89us,34us total 469.863ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 469.006ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 469.128ms
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 25.254ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 25.648ms
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Starting a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Clamp target GC heap from 350MB to 256MB
I/s.iturn.trainer(23991): Background concurrent copying GC freed 1841KB AllocSpace bytes, 0(0B) LOS objects, 0% free, 254MB/256MB, paused 99us,32us total 457.977ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 458.423ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 452.535ms
I/s.iturn.trainer(23991): Forcing collection of SoftReferences for 24B allocation
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Clamp target GC heap from 351MB to 256MB
I/s.iturn.trainer(23991): Alloc concurrent copying GC freed 996KB AllocSpace bytes, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 81us,34us total 889.822ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Background on Alloc for 852.759ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Alloc for 848.715ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Alloc for 254.614ms
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
W/s.iturn.trainer(23991): Throwing OutOfMemoryError "Failed to allocate a 24 byte allocation with 0 free bytes and 0B until OOM, target footprint 268435456, growth limit 268435456" (VmSize 22783260 kB)
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 16.107ms
I/s.iturn.trainer(23991): WaitForGcToComplete blocked Alloc on Background for 13.482ms
E/AndroidRuntime(23991): FATAL EXCEPTION: pool-16-thread-7
E/AndroidRuntime(23991): Process: com.ucmonks.iturn.trainer, PID: 23991
E/AndroidRuntime(23991): java.lang.OutOfMemoryError: Failed to allocate a 24 byte allocation with 0 free bytes and 0B until OOM, target footprint 268435456, growth limit 268435456
E/AndroidRuntime(23991): 	at java.util.HashMap.newNode(HashMap.java:1907)
E/AndroidRuntime(23991): 	at java.util.HashMap.putVal(HashMap.java:636)
E/AndroidRuntime(23991): 	at java.util.HashMap.put(HashMap.java:617)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertObject(UserDataWriter.java:101)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:67)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertArray(UserDataWriter.java:140)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:69)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertObject(UserDataWriter.java:101)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:67)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertArray(UserDataWriter.java:140)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:69)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertObject(UserDataWriter.java:101)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:67)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertArray(UserDataWriter.java:140)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:69)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertObject(UserDataWriter.java:101)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:67)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertArray(UserDataWriter.java:140)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:69)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertObject(UserDataWriter.java:101)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:67)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertObject(UserDataWriter.java:101)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertValue(UserDataWriter.java:67)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.UserDataWriter.convertObject(UserDataWriter.java:101)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.DocumentSnapshot.getData(DocumentSnapshot.java:148)
E/AndroidRuntime(23991): 	at com.google.firebase.firestore.QueryDocumentSnapshot.getData(QueryDocumentSnapshot.java:83)
E/AndroidRuntime(23991): 	at io.flutter.plugins.firebase.firestore.utils.PigeonParser.toPigeonDocumentSnapshot(PigeonParser.java:138)
E/AndroidRuntime(23991): 	at io.flutter.plugins.firebase.firestore.utils.PigeonParser.toPigeonDocumentSnapshots(PigeonParser.java:151)
E/AndroidRuntime(23991): 	at io.flutter.plugins.firebase.firestore.utils.PigeonParser.toPigeonQuerySnapshot(PigeonParser.java:68)
E/AndroidRuntime(23991): 	at io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin.lambda$queryGet$17(FlutterFirebaseFirestorePlugin.java:763)
E/AndroidRuntime(23991): 	at io.flutter.plugins.firebase.firestore.FlutterFirebaseFirestorePlugin$$ExternalSyntheticLambda12.run(D8$$SyntheticClass:0)
E/AndroidRuntime(23991): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156)
E/AndroidRuntime(23991): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651)
E/AndroidRuntime(23991): 	at java.lang.Thread.run(Thread.java:1119)
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/s.iturn.trainer(23991): Waiting for a blocking GC Alloc
I/Process (23991): Sending signal. PID: 23991 SIG: 9
Lost connection to device.

Flutter dependencies

Expand Flutter dependencies snippet
  firebase_core: ^3.5.0
  cloud_firestore: ^5.4.2
  firebase_analytics: ^11.3.2
  firebase_auth: ^5.3.0
  firebase_messaging: ^15.1.2
  firebase_storage: ^12.3.1
  firebase_app_check: ^0.3.2
  cloud_functions: ^5.1.2

Additional context and comments

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions