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.
var image
première ligne de lagetCropImage(...)
n'est pas publiée après l'utilisation, alors essayez d'utiliservar image
comme 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 appelerSystem.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é. :)Réponses:
Pour essayer de reproduire avec votre échantillon, j'ai dû d'abord convertir à partir d'une interface utilisateur.
Exécutez une version simplifiée de votre exemple:
Mais je n'ai pas pu voir la mémoire devenir incontrôlable. Vous avez donc probablement quelque chose d'autre à faire.
la source
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
la source