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

MiniProfiler未正确释放Timings引发内存泄漏问题求助

MiniProfiler中Timings对象无法正常释放引发内存泄漏问题

我在使用MiniProfiler开展性能分析时,发现组件存在无法正确Dispose/释放Timings对象的问题,存在潜在内存泄漏风险。

我使用Jetbrains DotMemory工具在测试工作负载执行前后分别抓取内存快照,发现测试过程中生成的1000个Timings对象始终被MiniProfiler实例持有,无法被垃圾回收。若用户使用该工具分析大量长文本数据库查询等场景,该问题将引发严重的内存占用异常。

最小复现代码如下:

public static void Main()
{
    try
    {
        // 在此处抓取第一次内存快照
        Console.ReadKey();
        var mp = MiniProfiler.StartNew();
        var rnd = new Random();
        for (int j = 0; j < 1000; j++)
        {
            using (mp.Step("outer"))
            {
                rnd.Next();
            }
        }
        
        Console.WriteLine(MiniProfiler.Current.RenderPlainText());

        mp.Stop(true);
        mp = null;

        if (Debugger.IsAttached)
            Console.ReadKey();
            // 在此处抓取第二次内存快照
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

感谢各位提供的帮助!

我对问题做了补充,新增更贴近实际场景的复现示例:感谢@Ed Pavlov的解答,但在更复杂的测试场景下Timings对象仍无法被正常释放。第二个示例基于Release配置编译,执行数据库SQL查询逻辑,我特意使用了较长的命令文本以稳定复现该现象:

public static async Task Main()
{
    try
    {
        Console.ReadLine();
        await DoStuff();
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

internal static async Task DoStuff()
{
    var mp = MiniProfiler.StartNew("Test");
    for (int i = 0; i < 5000; i++)
    {
        await Test();
        if (i % 200 == 0) Console.WriteLine(i);
    }
    Console.WriteLine(MiniProfiler.Current?.RenderPlainText());
    await mp.StopAsync(true);
}

public static async Task Test()
{
    var rnd = new Random();
    var txt = CommandFacade.CommandText.Replace("@@ID@@", rnd.Next(3000).ToString());

    using (MiniProfiler.Current.Step("Level 1"))
    using (var conn = GetConnection())
    using (var cmd = new ProfiledDbCommand(new SqlCommand(txt), conn, null))
    {
        await conn.OpenAsync();
        await cmd.ExecuteNonQueryAsync();

        conn.Close();
    }
}
public static DbConnection GetConnection()
{
    DbConnection cnn = new SqlConnection(ConnectionString);
    if (MiniProfiler.Current != null)
    {
        cnn = new ProfiledDbConnection(cnn, MiniProfiler.Current);
    }
    return cnn;
}

新示例对应的dotMemory内存快照包含两类内容:

  • DotMemory内存占用概览
  • 留存Timings对象的引用链详情

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:03:41