¿Hay algún problema de memoria con el aislamiento en la aplicación flutter?

9

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.

hoangquyy
fuente
¿Puedes compartir más código? Especialmente el método de cálculo.
Esen Mehmet
He agregado el código en edición, échale un vistazo. Gracias por responderme. @EsenMehmet
hoangquyy
¿Qué es el método de cálculo? ¿Qué es imglib? ¿Puedes, por favor, agregar más detalles?
Igor Kharakhordin
Puede leer el método de cálculo aquí: api.flutter.dev/flutter/foundation/compute.html , esa no es mi función de implementación, solo la uso. imglib es el paquete Image: pub.dev/packages/image . Lo siento, mi mala @IgorKharakhordin
hoangquyy
1
Creo que var imageen la primera línea del getCropImage(...)no se libera después del uso, así que intente usarlo var imagecomo 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 llame System.gc() o métodos similares directamente (para forzar la desasignación de memoria), eso es síntoma de código roto y no optimizado. :)
Roberto Manfreda

Respuestas:

0

Para intentar reproducir con su muestra, primero tuve que convertir desde una interfaz de usuario.

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

Ejecute una versión simplificada de su muestra:

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

Pero no pude ver que la memoria se salía de control. Entonces probablemente tengas algo más que hacer.

TWL
fuente
¿Has comprobado la memoria en modo Perfil? ¿Qué versión de flutter estás usando? No estoy seguro, pero tal vez vino de la versión flutter. Alguien tiene el mismo problema que yo: - stackoverflow.com/questions/57826962/…
hoangquyy
Entonces creo que el problema no vino de mi código. He usado otra forma de resolver este problema pero ya no uso aislar. Sin embargo, es bueno resolver este problema de memoria, gracias.
hoangquyy
0

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

Parth Dave
fuente