Há um problema de memória com o isolate no aplicativo flutter?

9

Estou com um problema de memória com o aplicativo flutter, ao usar computação, coloquei esta linha no parâmetro de função em computação:

var image = imglib.Image.fromBytes(values[1].width, values[1].height, values[1].planes[0].bytes, format: imglib.Format.bgra);

E execute-o em loop, a memória continuará crescendo toda vez que a memória ficará insuficiente e o aplicativo travou.

Se eu não tiver essa linha, a memória é estável em 40mb. Então, acho que, na computação, não foi limpo após o término da função de computação.

Alguém tem o mesmo problema?

Editar:

É assim que eu implemento a computação:

image = await compute(getCropImage, [copyFaces, streamImg]);

Em 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());
}

Com o imglib está o pacote Image:

import 'package:image/image.dart' as imglib;

Toda vez que eu chamo isso, a memória continua crescendo.

hoangquyy
fonte
Você pode compartilhar mais código? Especialmente o método de computação.
Esen Mehmet
Eu adicionei o código na edição, confira. Obrigado por me responder. @EsenMehmet
hoangquyy
O que é o método de computação? O que é imglib? Você pode, por favor, adicionar mais detalhes?
Igor Kharakhordin 3/11
Você pode ler o método de computação aqui: api.flutter.dev/flutter/foundation/compute.html , essa não é a minha função de implemento, eu apenas a uso. imglib é o pacote Image: pub.dev/packages/image . Desculpe meu mal @IgorKharakhordin
hoangquyy
11
Eu acho que a var imageprimeira linha do getCropImage(...)release não é liberada após o uso, então tente usar var imagecomo campo (para não alocar sempre nova memória), talvez seja útil não instanciar uma nova var a cada etapa do loop! Sempre tente reutilizar esses tipos de objetos, especialmente quando você estiver gerenciando com objetos grandes, como imagens. Geralmente, o coletor de lixo não garante a liberação de todos os objetos não utilizados. E lembre-se, nunca chame System.gc() métodos semelhantes diretamente (para forçar a desalocação da memória), isso é sintoma de código quebrado e não otimizado. :)
Roberto Manfreda

Respostas:

0

Para tentar reproduzir com sua amostra, tive que converter de uma interface do usuário.

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

Execute uma versão simplificada do seu exemplo:

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

Mas não consegui ver a memória fora de controle. Então você provavelmente tem mais alguma coisa acontecendo.

TWL
fonte
Você verificou a memória no modo de perfil? Qual versão do flutter você está usando? Não tenho certeza, mas talvez tenha vindo da versão flutuante. Alguém tem o mesmo problema que eu: - stackoverflow.com/questions/57826962/…
hoangquyy
Então, acho que o problema não veio do meu código. Eu usei outra maneira de resolver esse problema, mas não usando mais o isolate. No entanto, é bom resolver esse problema de memória, obrigado.
hoangquyy
0

Para um iniciante como nós, precisamos entender que a função de computação nada mais é do que o próprio isolado. e quanto mais você chamar para criar isolado, mais memória será necessária. Essa referência O spawn de Isolates terá ~ 2mb de ram e, portanto, precisamos tornar os isolados o menos possível, mesmo que você possa dizer que estou apenas computando e retornando resultados para que o isolate possa receber uma chamada do GC, mas não por vez. o armazenamento em cache ou a execução de algo com isolate ou com seu código nesse isolate pode impactar uma enorme pegada na memória.

então, ao invés disso, sugiro que você crie um isolado e faça o que quiser e quando terminar todas as faces de cópia, feche o isolado.

assista a este vídeo também para saber como usar o isolado

Parth Dave
fonte