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.
var image
in der ersten Zeile desgetCropImage(...)
nicht nach der Verwendung freigegeben wird, also versuchen Sie esvar image
als 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, niemalsSystem.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. :)Antworten:
Um zu versuchen, mit Ihrem Beispiel zu reproduzieren, musste ich zuerst von einer Benutzeroberfläche konvertieren. Bild:
Führen Sie eine vereinfachte Version Ihres Beispiels aus:
Aber ich konnte nicht sehen, dass die Erinnerung außer Kontrolle geriet. Sie haben also wahrscheinlich noch etwas anderes vor.
quelle