Gibt es ein Speicherproblem mit Isolate in der Flatter-App?

9

Ich habe ein Problem mit dem Speicher mit der Flatter-App. Wenn ich compute verwende, setze ich diese Zeile in den Funktionsparameter in compute:

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

Und führen Sie es in einer Schleife aus. Der Speicher wächst jedes Mal, wenn der Speicher knapp wird und die App abstürzt.

Wenn ich diese Zeile nicht habe, ist der Speicher bei 40 MB stabil. Ich denke also, dass es beim Rechnen nach Abschluss der Rechenfunktion nicht bereinigt wurde.

Hat jemand das gleiche Problem?

Bearbeiten:

So implementiere ich compute:

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

In 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());
}

Mit imglib ist das Image-Paket:

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

Jedes Mal, wenn ich das nenne, wächst die Erinnerung weiter.

hoangquyy
quelle
Können Sie mehr Code teilen? Besonders die Berechnungsmethode.
Esen Mehmet
Ich habe den Code in edit hinzugefügt, check it out. Danke für die Antwort. @ EsenMehmet
Hoangquyy
Was ist eine Berechnungsmethode? Was ist imglib? Können Sie bitte weitere Details hinzufügen?
Igor Kharakhordin
Sie können die Berechnungsmethode hier lesen: api.flutter.dev/flutter/foundation/compute.html , das ist nicht meine Implementierungsfunktion, ich benutze sie einfach. imglib ist das Paket Image: pub.dev/packages/image . Entschuldigung mein schlechtes @IgorKharakhordin
hoangquyy
1
Ich denke, dass das var imagein der ersten Zeile des getCropImage(...)nicht nach der Verwendung freigegeben wird, also versuchen Sie es var imageals Feld zu verwenden (um nicht immer neuen Speicher zuzuweisen), kann vielleicht nützlich sein, um nicht bei jedem Schleifenschritt eine neue Variable zu instanziieren! Versuchen Sie immer, diese Objekttypen wiederzuverwenden, insbesondere wenn Sie mit großen Objekten wie Bildern arbeiten. Im Allgemeinen garantiert der Garbage Collector nicht, dass alle nicht verwendeten Objekte freigegeben werden. Und denken Sie daran, niemals System.gc() direkte Methoden oder ähnliche Methoden aufzurufen (um die Freigabe des Speichers zu erzwingen). Dies ist ein Symptom für fehlerhaften und nicht optimierten Code. :)
Roberto Manfreda

Antworten:

0

Um zu versuchen, mit Ihrem Beispiel zu reproduzieren, musste ich zuerst von einer Benutzeroberfläche konvertieren. Bild:

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;
}

Führen Sie eine vereinfachte Version Ihres Beispiels aus:

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;
}

Aber ich konnte nicht sehen, dass die Erinnerung außer Kontrolle geriet. Sie haben also wahrscheinlich noch etwas anderes vor.

TWL
quelle
Haben Sie den Speicher im Profilmodus überprüft? Welche Flatterversion verwenden Sie? Ich bin mir nicht sicher, aber vielleicht kam es von der Flatterversion. Jemand hat das gleiche Problem wie ich: - stackoverflow.com/questions/57826962/…
hoangquyy
Ich denke, das Problem ist nicht auf meinen Code zurückzuführen. Ich habe dieses Problem auf andere Weise gelöst, aber nicht mehr isoliert. Es ist jedoch gut, dieses Speicherproblem zu lösen, danke.
Hoangquyy