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.


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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.