【问题标题】:Flutter images memory does not get gc颤振图像内存没有得到 gc
【发布时间】:2020-06-02 09:15:07
【问题描述】:

我有一个页面小部件,可以在 Android 设备上使用 Image.network() 显示一长串图像。经过长时间的滚动并显示每张图像后,内存增加了很多,达到 200MB。该应用程序在 atm 上运行良好,然后我离开页面,调用 dispose()。但是,内存使用量仍然没有减少。

从图中可以看出,外部内存占用了 186MB 的空间,并且永不停机。我阅读了 devTool 文档,外部存储器是本机对象。但是为什么不收集垃圾呢?或者也许这只是 android 管理内存的方式?

请在下面查看我的示例代码。我将它放在 tabbarviews 中,当我选择另一个选项卡时,页面会被处理。

class TestScreen extends StatefulWidget {
  const TestScreen({Key key}) : super(key: key);

  @override
  createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> with SingleTickerProviderStateMixin {

  List<Product> products = [];

  @override
  void initState() {
    super.initState();
    print("initState");
    fetchProducts();
  }

  @override
  void dispose() {
    print("dispose");
    super.dispose();
  }

  Future fetchProducts() async {
    //get the list of products
    setState(() {
      products = ...;
    });
  }

  @override
  Widget build(BuildContext context) {
    ThemeData theme = Theme.of(context);
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
      body: GridView.builder(
          itemCount: products.length,
          padding: EdgeInsets.all(4.0),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              mainAxisSpacing: 2.0,
              crossAxisSpacing: 2.0,
              childAspectRatio: 0.8),
          itemBuilder: (context, position) {
            final product = products[position];
            final imageData = product.mainImage;
            if (imageData != null && imageData.downloadURL != null) {
              return Image.network(
                imageData.downloadURL,
                fit: BoxFit.fill,
              );
            } else {
              return Image.asset("assets/images/product_image_placeholder.jpg");
            }
          }),
      ),
    );
  }
}

【问题讨论】:

  • 我认为你应该清理图像缓存
  • @veneno 你能把你的示例代码放上来吗?
  • PaintingBinding.instance.imageCache.clear(); 丢弃前先试试
  • @veneno 它有效!谢谢你,先生。我还有一个问题,让内存缓存保持原样并让它自行管理是否安全?我不知道在这种情况下内存管理是如何工作的。

标签: image flutter memory-leaks


【解决方案1】:

图像小部件保留缓存的图像,在某些情况下不会释放内存。那是knownissue,截至 2020 年 11 月 2 日仍在营业。

如果您查看 _Int64List 变量,您可以使用 DevTools Profiling 进行检查。当您使用新实例更新映像时,它会增长。

作为目前的解决方法,我们手动清除每个 build()dispose() 上的缓存:

 PaintingBinding.instance.imageCache.clear();
 PaintingBinding.instance.imageCache.clearLiveImages();

【讨论】:

  • 很遗憾,您的解决方法无法解决问题。
【解决方案2】:

使用这个包disposable_cached_images

【讨论】:

    猜你喜欢
    • 2022-06-17
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多