image - Flutter图像内存未得到gc

标签 image flutter memory-leaks

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

enter image description here

从图中可以看出,外部存储器占用了186MB的空间,并且永远不会下降。我读了 devTool 文档,外部内存是 native 对象。但为什么它们不被垃圾收集呢?或者也许这只是 Android 管理内存的方式?

请检查下面我的示例代码。我将其放置在选项卡 View 中,当我选择另一个选项卡时,页面将被释放。

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");
            }
          }),
      ),
    );
  }
}

最佳答案

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

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

enter image description here

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

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

关于image - Flutter图像内存未得到gc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60279392/

相关文章:

ios - 我可以在没有 Apple 开发者帐户的情况下使用 TestFairy 共享 iOS 调试应用程序吗?

macos - Valgrind 支持 Mac OS 10.8 吗?

memory-leaks - 非ARC项目:NSMutableArray,NSString内存泄漏

image - 如何在收到的 Gmail 邮件中插入图像

flutter - 如何将两个容器叠放在一起?

dart - 如何使用 PageController 的当前值更新子部件(加载指示器)?

c# - 我必须在 C# 中处理参数吗?

html - 如何在内容CSS3中隐藏图像地址

r - 以方形马赛克打印一组图像

javascript - 将鼠标悬停在效果上将图像向下推