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

Net6 Worker Service中Serilog记录SqlConnection异常引发内存泄漏

问题:Net6 Worker Service记录SqlConnection异常时内存飙升至8GB

我有一个Net6 Worker Service项目,使用Serilog.ILogger将错误日志写入TXT文件,近期内存占用飙升至8GB。该Worker仅负责三件事:通过Dapper从数据库获取数据、返回数据、发送邮件。

关键信息

  • 使用的Serilog相关包版本:
    • Serilog.Extensions.Hosting 5.0.0
    • Serilog.Sinks.File 5.0.0
  • 内存上涨触发条件:仅当捕获SqlConnection类型异常并记录日志时,内存占用才会增加,其他类型异常无此情况。
  • 当前日志记录代码:
_logger.LogError("InterfaceLogsCleanerWorker executed with exceptions" + ex.Message);
  • 数据获取代码:
public async Task<List<SetupDTO>> Get()
{
    var map = new Sys_SetupMap();
    var result = new TransacResult(true, MessageTransactResult.OK);

    List<Sys_Setup> entityList;
    List<SetupDTO> list = new List<SetupDTO>();
    using (var conn = new SqlConnection(this.connectionString))
    {
        var parameters = new DynamicParameters();
        parameters.Add("Result", string.Empty, DbType.String, ParameterDirection.Output);

        entityList = (await conn.QueryAsync<Sys_Setup>("GetSys_Setup", parameters, commandType: CommandType.StoredProcedure)).AsList();
    }

    foreach (var entity in entityList)
    {
        list.Add(map.EntityToDTO(entity));
    }

    return list;
}

问题根源分析

  1. 日志记录方式错误:当前代码直接拼接ex.Message,未将异常对象传递给Serilog。SqlConnection异常通常包含大量内部状态(如连接池信息、资源引用链),直接拼接消息会导致异常对象无法被GC正常回收——要么字符串引用了异常的部分内容,要么Serilog处理时意外持有了整个异常对象的引用,进而引发内存泄漏。
  2. 可能缺失日志滚动策略:若未配置日志文件按大小/时间滚动,单个日志文件过大可能导致内存中缓存的日志内容无法释放,但此情况不会仅在SqlConnection异常时触发,优先级低于前者。

修复方案

  1. 正确传递异常对象给Serilog:使用LogError的重载方法传入异常对象,让Serilog正确处理异常序列化,避免持有无效引用:
_logger.LogError(ex, "InterfaceLogsCleanerWorker executed with exceptions");
  1. 配置日志滚动策略:确保文件Sink设置了滚动规则,防止单文件过大占用内存:
Log.Logger = new LoggerConfiguration()
    .WriteTo.File(
        path: "logs/log-.txt",
        rollingInterval: RollingInterval.Day,
        fileSizeLimitBytes: 1024 * 1024 * 100, // 单文件最大100MB
        retainedFileCountLimit: 30) // 保留最近30个日志文件
    .CreateLogger();
  1. 验证资源释放逻辑:虽然代码用using包裹了SqlConnection,但需检查Sys_Setup实体是否包含未实现IDisposable的资源,避免Dapper返回的对象持有无效引用。
  2. 升级Serilog包版本:当前使用的5.0.0版本存在已知内存泄漏风险,建议升级至最新稳定版。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:08