Tengo un problema sobre la memoria con la aplicación flutter, cuando uso compute, pongo esta línea en el parámetro de función en compute:
var image = imglib.Image.fromBytes(values[1].width, values[1].height, values[1].planes[0].bytes, format: imglib.Format.bgra);
Y ejecútelo en bucle, la memoria sigue creciendo cada vez que se queda sin memoria y la aplicación se bloquea.
Si no tengo esa línea, la memoria es estable en 40mb. Así que creo que en computación, no se ha limpiado después de que finaliza la función de computación.
Alguien tiene el mismo problema?
Editar:
Así es como implemento el cálculo:
image = await compute(getCropImage, [copyFaces, streamImg]);
En 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());
}
Con imglib es el paquete de imagen:
import 'package:image/image.dart' as imglib;
Cada vez que llamo a esto, la memoria sigue creciendo.
var image
en la primera línea delgetCropImage(...)
no se libera después del uso, así que intente usarlovar image
como campo (para no asignar siempre memoria nueva), ¡tal vez pueda ser útil para no crear una nueva var en cada paso del bucle! Siempre intente reutilizar este tipo de objetos, especialmente cuando maneja con objetos grandes como imágenes. En general, el recolector de basura no garantiza liberar todos los objetos no utilizados. Y recuerde, nunca llameSystem.gc()
o métodos similares directamente (para forzar la desasignación de memoria), eso es síntoma de código roto y no optimizado. :)Respuestas:
Para intentar reproducir con su muestra, primero tuve que convertir desde una interfaz de usuario.
Ejecute una versión simplificada de su muestra:
Pero no pude ver que la memoria se salía de control. Entonces probablemente tengas algo más que hacer.
fuente
Para un principiante como nosotros, debemos entender que la función de cálculo no es más que el aislamiento en sí. y cuanto más llame para crear aislamiento, más memoria necesitará. Esta generación de aislamientos de referencia tomará ~ 2 mb de ram y, por lo tanto, debemos hacer los aislamientos lo menos posible, aunque podría decir que solo estoy calculando y devolviendo el resultado, por lo que aislar podría recibir una llamada de GC pero no a la vez podría desplazarse y almacenar en caché o hacer algo con aislar o su código dentro de ese aislante puede afectar la gran huella en memoria.
así que más bien, sugiero que cree un aislamiento y haga lo que quiera hacer y cuando termine de copiar todas las caras, cierre el aislamiento.
mira este video también para saber cómo usar aislar
fuente