如何解决Boost Log 1.64.0版本内存持续增长致OOM的问题?
修复Boost Log 1.64.0多线程日志内存泄漏问题
我之前也碰到过老版本Boost Log的这类内存泄漏问题,咱们来拆解下问题根源和修复方案:
问题本质
Boost Log 1.64.0的synchronous_sink在多线程高频率持续日志场景下,存在内部日志元数据和临时对象未正确回收的缺陷,导致内存不断累积。另外,你当前代码里的文件流没有配置缓冲,频繁的磁盘IO会让待写入的日志数据在内存里堆积,进一步加重内存压力。
具体修复方案
替换为异步Sink(核心修复)
把synchronous_sink换成asynchronous_sink,异步Sink会把日志处理逻辑放到后台线程,并且有更完善的内存回收机制,能避免同步场景下的内存堆积。修改后的Sink创建代码如下:// 替换原同步Sink为异步Sink shared_ptr< sinks::asynchronous_sink< sinks::text_ostream_backend > > sink( new sinks::asynchronous_sink< sinks::text_ostream_backend >( keywords::queue_capacity = 1000, // 设置队列容量,限制内存占用上限 keywords::thread_count = 2 // 根据磁盘IO性能调整后台线程数 ) );给文件流配置缓冲区
为std::ofstream设置合适的缓冲区大小,减少磁盘IO频率,避免待写入日志在内存中大量堆积:shared_ptr< std::ostream > strm(new std::ofstream("test.log")); if (!strm->good()) { throw std::runtime_error("Failed to open a text log file"); } // 设置64KB的文件流缓冲区 const size_t buffer_size = 65536; char* buffer = new char[buffer_size]; static_cast<std::ofstream*>(strm.get())->rdbuf()->pubsetbuf(buffer, buffer_size);使用线程本地日志器(可选优化)
不要依赖全局日志器,每个线程创建本地日志器实例,减少全局状态的竞争,提升内存使用效率:void thread_fun(boost::barrier& bar) { bar.wait(); src::logger_mt local_logger; // 线程本地日志器 while(1) { BOOST_LOG(local_logger) << "Log record Log record Log record Log record Log record Log record Log record Log record "; } }升级Boost版本(推荐)
Boost Log在1.65.0及后续版本中修复了多个内存泄漏问题,尤其是同步Sink和全局属性管理相关的bug。如果条件允许,直接升级到最新稳定版Boost库,从根源上解决这类已知问题。
效果验证
应用上述修复后,内存占用会稳定在合理范围,不会再持续上升。异步Sink会及时处理日志记录并回收相关对象内存,即使日志生成频率很高也能保持内存稳定。
内容的提问来源于stack exchange,提问作者Paul.Kim
相关产品推荐
相关产品推荐

