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

使用spdlog库调用Logger方法时内存泄漏,求代码问题排查

spdlog调用info/debug时内存泄漏问题排查

问题根源分析

1. 静态容器Sinks导致资源无法释放

代码中的Sinks是全局静态vector<spdlog::sink_ptr>,每次调用CreateLogger都会向其中添加新的sink实例:

  • CombinedLogger构造时会持有这些sink的shared_ptr(spdlog的logger内部会保存sink的引用)
  • 静态Sinks本身也持有这些sink的shared_ptr,导致sink的引用计数永远无法降到0,无法被销毁
  • 若多次调用CreateLogger,会持续积累无法回收的sink对象,直接引发内存泄漏

2. 重复注册Logger的隐患

如果多次调用CreateLogger,重复执行spdlog::register_logger(CombinedLogger)会导致:

  • spdlog全局注册表持有旧Logger的shared_ptr
  • 静态CombinedLogger又持有新Logger的引用,旧资源无法被回收,进一步加剧内存泄漏

修复方案

1. 移除静态sink容器,让Logger管理sink生命周期

将全局静态Sinks替换为函数内的局部容器,构造Logger后不再持有sink引用,让Logger完全负责sink的生命周期:

static std::shared_ptr<class spdlog::logger> CombinedLogger;

bool CreateLogger(const char *loggerName, const char* logName, std::chrono::seconds interval, const char* logFormat)
{
    // 局部sink容器,函数结束后自动销毁,不再持有sink引用
    std::vector<spdlog::sink_ptr> local_sinks;
    local_sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
    local_sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(logName)); 
    CombinedLogger = std::make_shared<spdlog::logger>(loggerName, begin(local_sinks), end(local_sinks));

    CombinedLogger->flush_on(spdlog::level::err);
    spdlog::flush_every(interval);
    CombinedLogger->set_pattern(logFormat);

    // 注册前检查是否已存在,避免重复注册
    if (spdlog::get(loggerName) == nullptr) {
        spdlog::register_logger(CombinedLogger);
    }
    return true;
}

2. 确保Logger只初始化一次

在调用CreateLogger时,通过std::call_once保证初始化操作仅执行一次,避免重复创建sink和Logger:

static std::once_flag logger_init_flag;
std::call_once(logger_init_flag, [&](){
    Logger::CreateLogger(name, logName, std::chrono::seconds(LogFlushTimeSec), "%Y-%m-%d | %H:%M:%S.%f| %n| %^%-10l%$|  %v");
});
std::shared_ptr<spdlog::logger> logging = spdlog::get(LoggerName);
logging->info("Execution Time and Date:  {} ", std::ctime(&startTime));

3. 程序退出时清理spdlog资源

在程序退出阶段,调用spdlog::drop_all()销毁所有注册的Logger,释放相关内存资源:

// 程序退出前执行
spdlog::drop_all();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:35:05