【问题标题】:Memory increase when pick image from gallery in example of flutter plugin image_picker在颤振插件 image_picker 示例中从图库中选择图像时内存增加
【发布时间】:2020-01-13 21:06:44
【问题描述】:

我运行flutter的插件image_picker的示例。

当我从画廊中一张一张地挑选图像时,内存不断增加。理想情况下是memory should jump back,因为在这个示例应用中它是at most select one image

class _MyHomePageState extends State<MyHomePage> {
  File _imageFile;              <-- this one keep the file of selected image.
  dynamic _pickImageError;
  bool isVideo = false;
  VideoPlayerController _controller;
  String _retrieveDataError;

  void _onImageButtonPressed(ImageSource source) async {
    ...
    try {
      _imageFile = await ImagePicker.pickImage(source: source);  <--- how to set value
      setState(() {});
    } catch (e) {
      _pickImageError = e;
    }
    ...
  }

  @override
  Widget build(BuildContext context) {
    ...
    Image.file(_imageFile);   <-- how to use it to display UI.
    ...
  }
}

我的问题是dispose the resource使用的File如何?

【问题讨论】:

标签: flutter plugins imagepicker


【解决方案1】:

您可以使用ImagePickermaxHeightmaxWidth 参数来加载调整大小的图像。

例如

var image = await ImagePicker.pickImage(source: ImageSource.gallery, maxWidth: 600);

另外,如果你想显示或保存到文件系统,你可以使用FlutterNativeImage插件(内部使用ImagePicker插件),它采用图像路径和压缩值来压缩图像。

例如

var compressedImage = await FlutterNativeImage.compressImage(image.path, quality: 50);

参考:https://github.com/btastic/flutter_native_image

【讨论】:

  • 我的问题是为什么在演示项目中内存不断增加。
  • 因为您正在将位图加载到内存中,该位图的大小/像素可能更大。在加载到内存之前,您需要先压缩/调整图像大小。
  • When pick another image, the image object is released, the memory should reduce back.但它一直在增加。
  • Dart VM 发起 GC 后,内存将被释放。
  • 我在演示项目中做同样的选择视频,每次选择视频时内存都会减少。
【解决方案2】:

仅仅选择File 不会影响内存,因为File 只是一个引用,并不保存文件系统实体的实际字节。但是,从文件中创建 Image 会增加内存使用量,因为 Image 保存了它引用的 File 的所有字节(一旦它读取了所有字节)。

根据您目前分享的内容,我们无法判断这是否是代码问题。除非您一次维护对超过 1 个 Image 的引用,否则您的应用将使用的最小内存应该反映该图像的大小。我说 minimum 是因为垃圾收集不会过于激进,并且不会在您不再引用它时立即处理所有内容。只有当它知道它需要运行 GC 时才会运行 GC,这样应用程序不会被饿死并且操作系统也很高兴。我不知道这是否适用于 Flutter,但是对于原生 Android,它还取决于制造商对 Android OS 的定制,它可以要求应用程序以各种频率进行 GC。

在内存分配清晰可见的用例中,只需在加载第二张图像后点击 GC 按钮即可。如果内存下降到与加载单个图像相同的水平,那么一切都很好。如果没有,您可能会在代码中的某处维护对这些图像的意外引用。

原生 Android 也有这个奇怪的东西(可能取决于版本/制造商) - 这在一些较旧的三星设备上最为明显 - 最后 4 个位图被缓存并且您无法清除该缓存,并且取决于您必须处理的位图大小,该缓存可能占用了应用程序的几乎所有可用内存,并且您最终会遇到 OOM 错误......希望 Flutter 不会这样做,或者允许开发人员控制它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 2018-10-31
    • 2020-01-22
    • 1970-01-01
    • 2021-06-17
    相关资源
    最近更新 更多