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.
var image
primeira linha dogetCropImage(...)
release não é liberada após o uso, então tente usarvar image
como 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 chameSystem.gc()
métodos semelhantes diretamente (para forçar a desalocação da memória), isso é sintoma de código quebrado e não otimizado. :)Respostas:
Para tentar reproduzir com sua amostra, tive que converter de uma interface do usuário.
Execute uma versão simplificada do seu exemplo:
Mas não consegui ver a memória fora de controle. Então você provavelmente tem mais alguma coisa acontecendo.
fonte
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
fonte