Чи є проблема із пам’яттю з ізолятом у програмі «Flutter»?


9

У мене проблема з пам’яттю з програванням «flutter», коли під час використання обчислень я ставлю цей рядок у параметр функції в обчисленні:

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 є пакет Image:

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

Щоразу, коли я це називаю, пам'ять постійно зростає.


Чи можете ви поділитися ще кодом? Особливо обчислювальний метод.
Есен Мехмет

Я додав код у редагуванні, перевірити його. Дякую за відповідь. @EsenMehmet
hoangquyy

Що таке обчислювальний метод? Що таке імгліб? Чи можете ви, будь ласка, додати більше деталей?
Ігор Харахордін

Ви можете прочитати метод обчислення тут: api.flutter.dev/flutter/foundation/compute.html , це не моя функція реалізації, я просто її використовую. imglib - зображення пакета: pub.dev/packages/image . Вибачте мій поганий @IgorKharakhordin
hoangquyy

1
Я думаю, що var imageперший рядок getCropImage(...)не випуску після використання, тому спробуйте використовувати var imageяк поле (для того, щоб не виділяти завжди нову пам'ять), можливо, може бути корисним, щоб не створити новий var на кожному кроці циклу! Завжди намагайтеся повторно використовувати ці типи об’єктів, особливо коли ви керуєте великими об'єктами, такими як зображення. Зазвичай сміттєзбірник не гарантує звільнення всіх невикористаних предметів. І пам’ятайте, що ніколи не дзвоніть System.gc() або подібні методи безпосередньо (щоб змусити розібратися в пам'яті), це симптом зламаного і неоптимізованого коду. :)
Роберто Манфреда

Відповіді:


0

Щоб спробувати відтворити ваш зразок, мені спочатку довелося перетворити з ui.Image:

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

Але я не зміг побачити, як пам'ять вийшла з-під контролю. Тож у вас, мабуть, щось інше відбувається.


Ви перевірили пам'ять у режимі профілю? Яку версію флетера ви використовуєте? Я не впевнений, але, можливо, це вийшло з флетер-версії. Хто - то є така ж проблема , як і я: - stackoverflow.com/questions/57826962 / ...
hoangquyy


Тому я думаю, що проблема не виникла з мого коду. Я використовував інший спосіб вирішення цієї проблеми, але більше не використовую ізолят. Однак добре вирішити це питання пам’яті, дякую.
hoangquyy

0

Для початківця, як ми, ми повинні розуміти, що обчислювальна функція - це не що інше, як сам ізолят. і чим більше ви закликаєте створити ізоляцію, тим більше пам'яті вам буде потрібно. Цей посилання Isown spawn займе ~ 2 Мб оперативної пам’яті, і тому нам потрібно зробити якомога менше ізолятів, хоча ви можете сказати, що я просто обчислюю і повертаю результат, щоб ізоляція могла отримати виклик GC, але ні за той час, коли ви можете прокручувати а кешування чи щось із ізолятом чи кодом всередині цього ізоляту може вплинути на величезний слід у пам'яті.

тож, роблячи це, я пропоную вам створити один ізолят і робити все, що ви хочете зробити, і коли ви закінчите все, що копіюєте, обличчя закрийте ізолятом.

дивіться це відео також, щоб знати, як використовувати ізолят

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.