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

Blazor MAUI混合应用Base64图片内存泄漏原因咨询

Blazor MAUI (.NET 8) Base64图片展示内存泄漏问题分析

问题背景

使用.NET 8正式版开发Blazor MAUI混合应用,实现用户选择图片并展示功能时,采用Base64格式处理图片出现严重内存泄漏:每次上传图片后内存持续增长,GC无法回收多余内存,最终导致页面崩溃。

复现代码

初始实现的核心代码如下:

@page "/memory_leak"
@using System.Diagnostics

<MudStack Class="ma-4" AlignItems="AlignItems.Center">
    <MudPaper Class="pa-3" Elevation="3">
        @if (_imageBase64 is null)
        {
            <MudAlert Severity="Severity.Normal">Choose an Image</MudAlert>
        }
        else
        {
            <MudImage Height="400" Alt="pic" Class="rounded-lg" 
                      Src="@string.Concat("data:image/png;base64,", _imageBase64)" 
                      />
        }
    </MudPaper>
    <MudFileUpload T="IBrowserFile" FilesChanged="UploadFiles" Class="pa-3">
            <ButtonTemplate>
                <MudFab
                    Size="Size.Small"
                    HtmlTag="label"
                    Color="Color.Secondary"
                    Icon="@Icons.Material.Filled.Image"
                    Label="Load picture"
                    for="@context" />
            </ButtonTemplate>
        </MudFileUpload>
    <MudPaper Class="pa-3">Item 3</MudPaper>
</MudStack>

@code
{
    private string? _imageBase64;

    private async Task UploadFiles(IBrowserFile file)
    {
        Debug.WriteLine($"size:{file.Size}");
        await using var openReadStream = file.OpenReadStream(file.Size);
        byte[] buffer = new byte[file.Size];
        var readAsync = await openReadStream.ReadAsync(buffer);
        _imageBase64 = Convert.ToBase64String(buffer, 0, readAsync);
    }
}

排查过程

  1. 注释掉MudImage的Src绑定代码后,内存泄漏现象消失,确认泄漏与Base64图片展示逻辑直接相关。
  2. 替换为原生HTML <img>标签后,问题依然存在,排除MudBlazor组件的影响:
@* <MudImage Height="400" Alt="pic" Class="rounded-lg" 
          Src="@string.Concat("data:image/png;base64,", _imageBase64)" 
    /> *@

<img src="@string.Concat("data:image/png;base64,", _imageBase64)" class="rounded-lg" height="400px"/>

解决方案

通过JavaScript Object URL机制解决了内存泄漏问题,核心思路是利用浏览器原生API管理图片资源,主动释放旧资源:

@page "/memory_leak"
@inject IJSRuntime JS
@implements IDisposable

<MudStack Class="ma-4" AlignItems="AlignItems.Center">
    <MudPaper Class="pa-3" Elevation="3">
        @if (_imageUrl is null)
        {
            <MudAlert Severity="Severity.Normal">Choose an Image</MudAlert>
        }
        else
        {
            <img src="@_imageUrl" class="rounded-lg" height="400px"/>
        }
    </MudPaper>
    <MudFileUpload T="IBrowserFile" FilesChanged="UploadFiles" Class="pa-3">
            <ButtonTemplate>
                <MudFab
                    Size="Size.Small"
                    HtmlTag="label"
                    Color="Color.Secondary"
                    Icon="@Icons.Material.Filled.Image"
                    Label="Load picture"
                    for="@context" />
            </ButtonTemplate>
        </MudFileUpload>
    <MudPaper Class="pa-3">Item 3</MudPaper>
</MudStack>

@code
{
    private string? _imageUrl;
    private string? _currentObjectUrl;

    private async Task UploadFiles(IBrowserFile file)
    {
        // 释放旧的Object URL
        if (!string.IsNullOrEmpty(_currentObjectUrl))
        {
            await JS.InvokeVoidAsync("URL.revokeObjectURL", _currentObjectUrl);
        }

        // 创建新的Object URL
        _currentObjectUrl = await JS.InvokeAsync<string>("URL.createObjectURL", file);
        _imageUrl = _currentObjectUrl;
        StateHasChanged();
    }

    public void Dispose()
    {
        // 组件销毁时释放资源
        if (!string.IsNullOrEmpty(_currentObjectUrl))
        {
            _ = JS.InvokeVoidAsync("URL.revokeObjectURL", _currentObjectUrl);
        }
    }
}

问题根源分析

这并非代码用法错误,更可能是Blazor MAUI中WebView渲染引擎的内存管理问题:

  • 当Base64字符串绑定到<img>的src属性时,WebView底层渲染引擎(如Android WebView、iOS WKWebView)解析Base64为图片资源后,可能未正确释放对原始Base64字符串的引用;
  • Blazor更新_imageBase64时,旧的Base64字符串因被WebView持有,无法被.NET GC回收,导致内存持续累积;
  • Object URL机制通过浏览器原生API管理资源,可主动调用revokeObjectURL释放资源,从根源避免了引用泄漏。

内容的提问来源于stack exchange,提问作者fairjm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:46:04