Çırpınan uygulamada izolat ile ilgili bellek sorunu var mı?


9

Ben flutter uygulaması ile bellek hakkında bir sorun var, compute kullanırken, compute işlev parametresine bu satırı koymak:

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

Ve döngüde çalıştırın, bellek her zaman sonra bellek dışında büyümeye devam ve uygulama çöktü.

Bu çizgiye sahip değilsem, bellek 40mb'de sabittir. Bu yüzden hesaplamada, hesaplama fonksiyonu bittikten sonra temizlenmediğini düşünüyorum.

Aynı problemi olan var mı?

Düzenle:

Bu şekilde hesaplama uygulamak:

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

GetCropImage içinde:

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

İmglib ile Görüntü paketi:

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

Bunu her söylediğimde, bellek büyümeye devam ediyor.


Daha fazla kod paylaşabilir misiniz? Özellikle hesaplama yöntemi.
Esen Mehmet

Kodu düzenlemeye ekledim, kontrol et. Bana cevap verdiğiniz için teşekkürler. @EsenMehmet
hoangquyy

Hesaplama yöntemi nedir? İmglib nedir? Lütfen daha fazla ayrıntı ekleyebilir misiniz?
Igor Kharakhordin

Burada hesaplama yöntemini okuyabilirsiniz: api.flutter.dev/flutter/foundation/compute.html , bu benim uygulama fonksiyonu değil, sadece kullanıyorum. imglib paket Resim: pub.dev/packages/image . Üzgünüm benim kötü @IgorKharakhordin
hoangquyy

1
Ben kullanımdan sonra değil sürümü var imageilk satırında getCropImage(...), bu yüzden var imagealan olarak kullanmayı deneyin (her zaman yeni bellek ayırmak için değil), belki de her döngü adımında yeni bir var somutlaştırmak için yararlı olabilir! Her zaman bu tür nesneleri, özellikle görüntü gibi büyük nesnelerle yönetirken yeniden kullanmaya çalışın. Genellikle çöp toplayıcı kullanılmayan tüm nesnelerin serbest bırakılmasını garanti etmez. Ve unutmayın, asla doğrudan çağırma System.gc() veya benzer yöntemleri doğrudan (bellek ayırmayı zorlamak için), bu kırık ve optimize edilmemiş kod belirtisidir. :)
Roberto Manfreda

Yanıtlar:


0

Örneği ile çoğaltmak için, önce bir kullanıcı arabirimi dönüştürmek zorunda kaldı.

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

Örneğinizin basitleştirilmiş bir sürümünü çalıştırın:

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

Ama hafızanın kontrolden çıktığını göremedim. Yani muhtemelen başka bir şey oluyor.


Belleği Profil modunda kontrol ettiniz mi? Hangi çarpıntı sürümünü kullanıyorsunuz? Emin değilim ama belki de çarpıntı sürümünden geldi. Birinin benimle aynı sorunu var: - stackoverflow.com/questions/57826962/…
hoangquyy


Bence sorun kodumdan gelmedi. Bu sorunu çözmek için başka bir yol kullandım ama artık izolat kullanmıyorum. Ancak, bu bellek sorununu çözmek güzel, teşekkürler.
hoangquyy

0

Bizim gibi bir başlangıç ​​için, hesaplama fonksiyonunun izolatın kendisinden başka bir şey olmadığını anlamamız gerekir. ve izole etmek için ne kadar çok çağırırsanız o kadar çok hafızaya ihtiyacınız olacaktır. Bu referans Isolates spawn ~ 2mb koç alacak ve bu yüzden sadece hesaplama yaptığımı ve sonucu döndürdüğümü söyleseniz bile, izolat GC çağrısı alabilir, ancak aynı anda kaydırma yapıyor olabilirsiniz. ve izolatla veya bu izolat içindeki kodunuzla önbellekleme veya bir şey yapmak büyük bellek içi ayak izini etkileyebilir.

bunun yerine, bir izolat oluşturmanızı ve ne yapmak istediğinizi yapmanızı öneririm ve tüm kopyaları bitirdiğinizde izolatları kapatın.

izolat kullanmayı öğrenmek için de bu videoyu izleyin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.