Reputation: 2063
I have a problem about memory with flutter app, when using compute, I put this line in the function parameter in compute:
var image = imglib.Image.fromBytes(values[1].width, values[1].height, values[1].planes[0].bytes, format: imglib.Format.bgra);
And run it in loop, the memory keep growing everytime then out of memory and the app crashed.
If I don't have that line, the memory is stable at 40mb. So I think that in compute, it's not been cleaned up after the compute function finish.
Anyone have same problem?
Edit:
This is how I implement compute:
image = await compute(getCropImage, [copyFaces, streamImg]);
In 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());
}
With imglib is the Image package:
import 'package:image/image.dart' as imglib;
Everytime I call this, the memory keep growing.
Upvotes: 12
Views: 2209
Reputation: 2126
For a starter like us, we need to understand that compute function is nothing but the isolate itself. and the more you call to create isolate the more memory you will be needing. This reference Isolates spawn will take ~ 2mb of ram and so we need to make isolates as less as possible even though you might say that I'm just computing and returning result so isolate might get GC call but no at a time you might be scrolling and caching or doing something with isolate or your code within that isolate can impact huge in-memory footprint.
so rather doing that I suggest you create one isolate and do whatever stuff you want to do and when you finish all you copy faces then close the isolate.
watch this video also to know how to use isolate
Upvotes: 0
Reputation: 6646
To try to reproduce with your sample, I had to convert from a ui.Image first:
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;
}
The run a simplified version of your sample:
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;
}
But I wasn't able to see the memory go out of control. So you probably have something else going on.
Upvotes: 1