我有一个页面小部件,可以在 Android 设备上使用 Image.network() 显示一长串图像。经过长时间滚动并显示所有图像后,内存增加了很多,达到 200MB。该应用程序工作正常 atm,然后我离开页面,调用 dispose() 。然而,内存使用量仍然没有减少。
从图中可以看出,外部存储器占用了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 进行检查。当您使用新实例更新镜像时,它会不断增长。
作为目前的解决方法,我们手动清除每个 build()
和 dispose()
上的缓存:
PaintingBinding.instance.imageCache.clear();
PaintingBinding.instance.imageCache.clearLiveImages();
关于image - Flutter图像内存未得到gc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60279392/