使用Valgrind检测到Google Protobuf 3.5.1中MessageLite内存泄漏
Google Protobuf 3.5.1 MessageLite 疑似内存泄漏(Valgrind检测)
本人使用Google Protobuf 3.5.1版本,通过Valgrind检测时发现MessageLite存在疑似内存泄漏问题,具体检测日志如下:
==4096== 16 bytes in 1 blocks are possibly lost in loss record 397 of 2,856 ==4096== at 0x4C3217F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==4096== by 0x52AB2C4: Create<google::protobuf::internal::InternalMetadataWithArenaBase<google::protobuf::UnknownFieldSet, google::protobuf::internal::InternalMetadataWithArena>::Container> (arena.h:361) ==4096== by 0x52AB2C4: google::protobuf::internal::InternalMetadataWithArenaBase<google::protobuf::UnknownFieldSet, google::protobuf::internal::InternalMetadataWithArena>::mutable_unknown_fields_slow() (metadata_lite.h:153) ==4096== by 0x6504716: google::protobuf::internal::ReflectionOps::Clear(google::protobuf::Message*) (reflection_ops.cc:139) ==4096== by 0x6475627: InlineParseFromCodedStream (message_lite.cc:129) ==4096== by 0x6475627: InlineParseFromArray (message_lite.cc:142) ==4096== by 0x6475627: google::protobuf::MessageLite::ParseFromString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (message_lite.cc:207)
请问是否有开发者遇到过此类问题?
问题说明与解决方案
这个问题在Protobuf 3.5.x系列版本中不少开发者都遇到过,属于Arena内存管理相关的已知问题:
- 从调用栈来看,问题出在解析包含未知字段的消息后调用
Clear操作时,Protobuf的InternalMetadata容器内存没有被Arena正确回收,Valgrind因此标记为"possibly lost"。 - 这类标记很多时候是误报:Arena分配器会缓存部分内存块用于后续复用,不会立即释放给系统,程序退出时所有Arena管理的内存都会被统一回收;但在3.5.1版本中确实存在部分场景下的小内存泄漏。
解决办法:
- 升级Protobuf版本:3.5.1是2018年的旧版本,后续3.6+版本修复了大量Arena相关的内存问题,3.8.x及以后版本对Valgrind的兼容性大幅提升,基本能消除这类误报和实际泄漏。
- 优化代码逻辑:尽量复用Message对象,减少频繁调用
Clear后重新解析的操作,降低内存分配触发的频率。 - 验证是否为真泄漏:如果无法升级版本,可通过长期运行测试观察内存是否持续增长。若只是Valgrind标记的"possibly lost"但内存没有持续上涨,说明是Arena缓存导致的误报,无需额外处理。
内容的提问来源于stack exchange,提问作者Britto
相关产品推荐
相关产品推荐

