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

CefSharp Offscreen浏览器BitmapBuffer内存无法释放问题

CefSharp Offscreen模式ChromiumWebBrowser实例BitmapBuffer内存泄漏问题

问题现象

  • 后台批量创建Offscreen模式的ChromiumWebBrowser实例执行任务,按预期逻辑关闭并释放实例后,每创建一个实例会残留约4MB名为BitmapBuffer的内存占用,该部分内存始终无法被GC回收。
  • 初始测试创建10个实例时内存占用约80MB,调整创建量到150个后内存占用达800MB,多次等待10-20分钟观测内存无自动释放,手动调用GC.Collect()也无改善。

复现代码

public static int Main(string[] args)
{
    CefSharpSettings.SubprocessExitIfParentProcessClosed = true;
    CefSharpSettings.WcfEnabled = false;

    var settings = new CefSettings()
    {
        //默认CefSharp使用内存缓存,指定缓存目录可持久化数据
        CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"),
    };

    settings.CefCommandLineArgs.Add("disable-gpu-compositing", string.Empty);

    Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

    for (int i = 0; i < 150; i++)
    {
        Thread.Sleep(1000);
        Task.Run(CreateAndDispose);
    }

    //手动调用GC.Collect()无任何效果
    Console.ReadKey();

    return 0;
}

public static async Task CreateAndDispose()
{
    var browser = new ChromiumWebBrowser("https://www.google.com/");

    browser.GetBrowser().CloseBrowser(true);
    browser.RenderHandler = null;
    browser.Dispose();
    browser = null;
}

内存观测截图

问题原因

  1. 释放时序错误:创建ChromiumWebBrowser实例后立即调用关闭和释放方法时,浏览器底层渲染进程还未完成初始化,CloseBrowser调用不会生效,底层持有的BitmapBuffer资源不会进入释放逻辑。
  2. 缺少生命周期等待:Offscreen模式的浏览器初始化、页面加载、关闭都是异步过程,直接同步调用Dispose不会等待渲染进程完成资源清理,会导致非托管位图缓冲区残留。
  3. RenderHandler资源未手动清理:默认RenderHandler持有共享内存的位图引用,仅把RenderHandler属性置空不会触发其内部非托管资源释放。

正确释放方案

核心操作要求

  • 必须等待BrowserInitialized事件触发、IsBrowserInitialized属性为true后,再执行关闭逻辑,禁止创建实例后立刻释放。
  • 调用CloseBrowser后要等待BrowserClosed事件触发,确认底层资源释放完成后再清理托管引用。
  • 浏览器关闭后主动调用RenderHandler的Dispose方法,不要仅将属性置空。
  • 不要无限制并发创建Offscreen浏览器实例,建议使用对象池复用实例,从根源减少频繁创建销毁的内存开销。

修正后的CreateAndDispose实现

public static async Task CreateAndDispose()
{
    var browser = new ChromiumWebBrowser("https://www.google.com/");
    try
    {
        // 等待浏览器初始化完成
        var initTcs = new TaskCompletionSource<bool>();
        EventHandler initHandler = null;
        initHandler = (s, e) =>
        {
            browser.BrowserInitialized -= initHandler;
            initTcs.TrySetResult(true);
        };
        browser.BrowserInitialized += initHandler;
        using var initCts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
        initCts.Token.Register(() => initTcs.TrySetResult(false));
        await initTcs.Task;

        // 等待浏览器关闭完成
        var closeTcs = new TaskCompletionSource<bool>();
        EventHandler<BrowserClosedEventArgs> closeHandler = null;
        closeHandler = (s, e) =>
        {
            browser.BrowserClosed -= closeHandler;
            closeTcs.TrySetResult(true);
        };
        browser.BrowserClosed += closeHandler;
        
        // 执行关闭
        browser.GetBrowser().CloseBrowser(true);
        
        using var closeCts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
        closeCts.Token.Register(() => closeTcs.TrySetResult(false));
        await closeTcs.Task;
    }
    finally
    {
        // 主动释放RenderHandler
        browser.RenderHandler?.Dispose();
        browser.RenderHandler = null;
        // 释放浏览器实例
        if (!browser.IsDisposed)
        {
            browser.Dispose();
        }
        browser = null;
    }
}

优化配置项

Cef初始化时可添加以下参数减少离屏渲染内存占用:

// 禁用离屏渲染共享位图缓存
settings.CefCommandLineArgs.Add("disable-bitmap-sharing", "1");
// 限制渲染进程数量,空闲时自动回收内存
settings.CefCommandLineArgs.Add("renderer-process-limit", "2");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:21:45