You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用PictureRecorder绘图调用picture.toImage后内存不释放如何处理

Flutter PictureRecorder调用toImage后内存无法释放解决方案
  • 首先排查运行模式:Debug模式下Flutter内存回收策略偏保守,不会及时释放无用内存,优先切换到Release模式复现验证,多数情况下内存会自动正常回落。
  • 手动清理图片缓存:如果Release模式仍存在内存不回落问题,可在所有相关ui.Image、Picture对象调用dispose()之后,主动清空Flutter全局图片缓存:
// 清空普通图片缓存
PaintingBinding.instance.imageCache.clear();
// 若仍有内存残留,可追加清空活跃图片引用(注意该操作会影响当前正在展示的其他图片,按需使用)
PaintingBinding.instance.imageCache.clearLiveImages();
  • 检查Flutter版本:Flutter 2.x版本存在Picture.toImage方法的已知引擎层内存泄露问题,升级到3.0及以上稳定版即可修复该问题。
  • 避免悬停异步任务:如果存在多次调用_getImage的场景,需要在页面销毁、或者重复调用时中断前次未完成的异步逻辑,避免未执行的回调持有图片对象导致无法释放。

优化后参考代码

bool _isDisposed = false;

@override
void dispose() {
  _isDisposed = true;
  super.dispose();
}

void _getImage() async {
  final imageFile = await _picker.getImage(source: ImageSource.gallery);
  if (_isDisposed || imageFile == null) {
    return;
  }
  Uint8List bytes = await imageFile.readAsBytes();
  if (_isDisposed) return;
  
  final Completer<ui.Image> completer = Completer();
  ui.decodeImageFromList(bytes, (ui.Image img) {
    if (!completer.isCompleted) {
      completer.complete(img);
    }
  });
  ui.Image? image;
  ui.Picture? picture;
  ui.Image? resultImage;
  try {
    image = await completer.future;
    if (_isDisposed) return;

    Size size = Size(image.width.toDouble(), image.height.toDouble());
    final recorder = ui.PictureRecorder();
    final canvas = Canvas(
        recorder,
        Rect.fromLTWH(
            0, 0, image.width.toDouble(), image.height.toDouble()));
    canvas.drawImageRect(
        image,
        ui.Rect.fromLTWH(
            0, 0, image.width.toDouble(), image.height.toDouble()),
        ui.Rect.fromLTWH(
            0, 0, image.width.toDouble(), image.height.toDouble()),
        Paint());

    image.dispose();
    picture = recorder.endRecording();
    resultImage = await picture.toImage(size.width.toInt(), size.height.toInt());
  } finally {
    image?.dispose();
    picture?.dispose();
    resultImage?.dispose();
    // 清理缓存释放内存
    PaintingBinding.instance.imageCache.clear();
  }
}

内容的提问来源于stack exchange,提问作者L.Han

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:24:03