Есть ли проблемы с памятью с изолятом в приложении флаттера?

9

У меня проблема с памятью в приложении flutter, при использовании compute я помещаю эту строку в параметр функции в compute:

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

И запустить его в цикле, память продолжает расти каждый раз, затем не хватает памяти и приложение падает.

Если у меня нет этой строки, память стабильна на 40 МБ. Так что я думаю, что в вычислениях он не был очищен после завершения функции вычисления.

У кого-нибудь есть такая же проблема?

Редактировать:

Вот как я реализую вычисления:

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

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

С imglib это пакет изображений:

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

Каждый раз, когда я это называю, память продолжает расти.

hoangquyy
источник
Можете ли вы поделиться больше кода? Особенно компьютерный метод.
Эсен Мехмет
Я добавил код в редактирование, проверьте его. Спасибо за ответ мне. @EsenMehmet
hoangquyy
Что такое метод вычисления? Что такое imglib? Можете ли вы добавить более подробную информацию?
Игорь
Вы можете прочитать метод вычисления здесь: api.flutter.dev/flutter/foundation/compute.html , это не моя функция реализации, я просто использую ее. imglib - это пакет Image: pub.dev/packages/image . Извините, мой плохой @IgorKharakhordin
hoangquyy
1
Я думаю, что var imageпервая строка getCropImage(...)не выпускается после использования, поэтому попробуйте использовать var imageполе as (чтобы не всегда выделять новую память), может быть полезно не создавать экземпляр нового var на каждом шаге цикла! Всегда старайтесь повторно использовать эти типы объектов, особенно когда вы управляете большими объектами, такими как изображения. Обычно сборщик мусора не гарантирует освобождение всех неиспользуемых объектов. И помните, никогда не вызывайте System.gc() или подобные методы напрямую (для принудительного освобождения памяти), это признак неисправного и неоптимизированного кода. :)
Роберто Манфреда

Ответы:

0

Чтобы попытаться воспроизвести с вашим образцом, мне пришлось преобразовать из пользовательского интерфейса. Изображение сначала:

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

Запустите упрощенную версию вашего образца:

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

Но я не смог увидеть, как память вышла из-под контроля. Так что у вас, вероятно, что-то еще происходит.

TWL
источник
Вы проверили память в режиме профиля? Какую версию флаттера вы используете? Я не уверен, но, возможно, это из-за флаттера. У кого-то
такая
И здесь: stackoverflow.com/questions/55695119/…
hoangquyy
Поэтому я думаю, что проблема не в моем коде. Я использовал другой способ решения этой проблемы, но больше не использовал изолят. Тем не менее, это хорошо, чтобы решить эту проблему с памятью, спасибо.
hoangquyy
0

Для такого начинающего, как мы, мы должны понимать, что вычислительная функция - это не что иное, как сам изолят. и чем больше вы вызываете для создания изоляции, тем больше памяти вам понадобится. Эта ссылка Spawn Isolates займет ~ 2 Мб оперативной памяти, и поэтому нам нужно сделать изоляторы как можно меньше, даже если вы скажете, что я просто вычисляю и возвращаю результат, поэтому изолят может получить вызов GC, но нет, в то время как вы можете прокручивать и кэширование или выполнение чего-либо с изолятом или вашим кодом в этом изоляте может повлиять на огромный объем памяти.

так что вместо этого я предлагаю вам создать один изолят и делать все, что вы хотите сделать, а когда вы закончите копирование граней, закройте изолят.

Посмотрите это видео, чтобы узнать, как использовать изолят

Парт Дэйв
источник