Mam problem z pamięcią z aplikacją trzepotania, podczas korzystania z obliczeń wstawiam ten wiersz w parametrze funkcji w obliczeniu:
var image = imglib.Image.fromBytes(values[1].width, values[1].height, values[1].planes[0].bytes, format: imglib.Format.bgra);
I uruchom go w pętli, pamięć ciągle rośnie, a następnie brak pamięci, a aplikacja uległa awarii.
Jeśli nie mam tej linii, pamięć jest stabilna przy 40 MB. Myślę więc, że w obliczeniach nie zostało wyczyszczone po zakończeniu funkcji obliczeń.
Czy ktoś ma ten sam problem?
Edytować:
Oto jak implementuję obliczenia:
image = await compute(getCropImage, [copyFaces, streamImg]);
W 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());
}
Z imglib jest pakiet Image:
import 'package:image/image.dart' as imglib;
Za każdym razem, gdy to nazywam, pamięć się powiększa.
var image
w pierwszym wierszugetCropImage(...)
nie ma wydania po użyciu, więc spróbuj użyćvar image
jako pola (aby nie przydzielać zawsze nowej pamięci), może być użyteczne, aby nie tworzyć nowej zmiennej na każdym kroku pętli! Zawsze staraj się ponownie wykorzystywać tego typu obiekty, zwłaszcza gdy zarządzasz dużymi obiektami, takimi jak obrazy. Ogólnie śmieciarz nie gwarantuje uwolnienia wszystkich nieużywanych obiektów. I pamiętaj, że nigdy nie wywoływajSystem.gc()
bezpośrednio lub podobnych metod (w celu wymuszenia zwolnienia pamięci), jest to objaw zepsutego i niezoptymalizowanego kodu. :)Odpowiedzi:
Aby spróbować odtworzyć z twoją próbką, musiałem najpierw przekonwertować z interfejsu użytkownika.
Uruchom uproszczoną wersję swojej próbki:
Ale nie byłem w stanie zobaczyć, jak pamięć wymyka się spod kontroli. Więc prawdopodobnie dzieje się coś innego.
źródło