Existe-t-il un problème de mémoire avec l'isolat dans l'application Flutter?


9

J'ai un problème de mémoire avec l'application flutter, lorsque j'utilise compute, je mets cette ligne dans le paramètre de fonction dans compute:

var image = imglib.Image.fromBytes(values[1].width, values[1].height, values[1].planes[0].bytes, format: imglib.Format.bgra);

Et exécutez-le en boucle, la mémoire continue de croître à chaque fois, puis la mémoire est insuffisante et l'application s'est bloquée.

Si je n'ai pas cette ligne, la mémoire est stable à 40 Mo. Je pense donc qu'en calcul, il n'a pas été nettoyé après la fin de la fonction de calcul.

Quelqu'un a le même problème?

Éditer:

Voici comment j'implémente le calcul:

image = await compute(getCropImage, [copyFaces, streamImg]);

Dans getCropImage:

Future<imglib.Image> getCropImage(List<dynamic> values) async {
  var image = imglib.Image.fromBytes(values[1].width, values[1].height, values[1].planes[0].bytes, format: imglib.Format.bgra);

  double topLeftX = values[0][0].boundingBox.topLeft.dx.round() -
  (values[0][0].boundingBox.width * 0.2);
  double topLeftY = values[0][0].boundingBox.topLeft.dy.round() -
  (values[0][0].boundingBox.height * 0.2);
  double width = values[0][0].boundingBox.width.round() +
  (values[0][0].boundingBox.width * 0.4);
  double height = values[0][0].boundingBox.height.round() +
  (values[0][0].boundingBox.height * 0.4);
  if (topLeftX <= 0) {
    topLeftX = 25;
  }
  if (topLeftY <= 0) {
    topLeftY = 25;
  }
  if ((topLeftX + width) >= values[1].width) {
    width = values[1].width - topLeftX - 25;
  }
  if ((topLeftY + height) >= values[1].height) {
    height = values[1].height - topLeftY - 25;
  }

  return imglib.copyCrop(
      image, topLeftX.round(), topLeftY.round(), width.round(), height.round());
}

Avec imglib est le paquet Image:

import 'package:image/image.dart' as imglib;

Chaque fois que j'appelle cela, la mémoire continue de croître.


Pouvez-vous partager plus de code? Surtout la méthode de calcul.
Esen Mehmet

J'ai ajouté le code en édition, vérifiez-le. Merci de me répondre. @EsenMehmet
hoangquyy

Qu'est-ce que la méthode de calcul? Qu'est-ce que l'imglib? Pouvez-vous, s'il vous plaît, ajouter plus de détails?
Igor Kharakhordin

Vous pouvez lire la méthode de calcul ici: api.flutter.dev/flutter/foundation/compute.html , ce n'est pas ma fonction d'implémentation, je l'utilise juste. imglib est le package Image: pub.dev/packages/image . Désolé mon mauvais @IgorKharakhordin
hoangquyy

1
Je pense que la var imagepremière ligne de la getCropImage(...)n'est pas publiée après l'utilisation, alors essayez d'utiliser var imagecomme champ (afin de ne pas allouer toujours de nouvelle mémoire), peut-être peut-être utile de ne pas instancier une nouvelle var à chaque étape de la boucle! Essayez toujours de réutiliser ces types d'objets, surtout lorsque vous gérez avec de gros objets tels que des images. Généralement, le garbage collector ne garantit pas de libérer tous les objets inutilisés. Et rappelez-vous, ne jamais appeler System.gc() directement ou des méthodes similaires (pour forcer la désallocation de mémoire), c'est le symptôme d'un code cassé et non optimisé. :)
Roberto Manfreda

Réponses:


0

Pour essayer de reproduire avec votre échantillon, j'ai dû d'abord convertir à partir d'une interface utilisateur.

Future<Uint8List> _bytePng(ui.Image image) async {
  ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.rawRgba);
  Uint8List byteList = byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
  return byteList;
}

Exécutez une version simplifiée de votre exemple:

imglib.Image image2 = await compute(_getImage, [image1.width, image1.height, byteList]);


Future<imglib.Image> _getImage(List<dynamic> values) async {
  var temp = imglib.Image.fromBytes(values[0], values[1], values[2], format: imglib.Format.bgra);

  var rng = new Random().nextInt(50);
  imglib.Image cropped = imglib.copyCrop(temp, 0, 0, temp.width - rng, temp.height - rng);

  return cropped;
}

Mais je n'ai pas pu voir la mémoire devenir incontrôlable. Vous avez donc probablement quelque chose d'autre à faire.


Avez-vous vérifié la mémoire en mode Profil? Quelle version de flutter utilisez-vous? Je ne suis pas sûr mais peut-être provenait-il d'une version flottante. Quelqu'un a le même problème que moi: - stackoverflow.com/questions/57826962/…
hoangquyy


Je pense donc que le problème ne vient pas de mon code. J'ai utilisé une autre méthode pour résoudre ce problème, mais je n'utilise plus d'isolat. Cependant, il est bon de résoudre ce problème de mémoire, merci.
hoangquyy

0

Pour un démarreur comme nous, nous devons comprendre que la fonction de calcul n'est rien d'autre que l'isolat lui-même. et plus vous appelez pour créer isoler, plus vous aurez besoin de mémoire. Cette référence de génération d'isolats prendra environ 2 Mo de RAM et nous devons donc réduire le plus possible les isolats même si vous pouvez dire que je ne fais que calculer et renvoyer des résultats afin que l'isolat puisse recevoir un appel GC, mais pas à un moment où vous faites défiler et la mise en cache ou faire quelque chose avec isolate ou votre code dans cet isolat peut avoir un impact énorme sur l'empreinte en mémoire.

donc plutôt faire cela, je vous suggère de créer un isolat et de faire tout ce que vous voulez faire et lorsque vous avez terminé tout ce que vous copiez faces puis fermez l'isolat.

regardez cette vidéo aussi pour savoir comment utiliser isoler

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.