【转】警惕多线程环境string、vector、protobuf等自增长数据结构的隐性内存泄露
2017-05-18 13:56
302 查看
转载自 警惕多线程环境string、vector、protobuf等自增长数据结构的隐性内存泄露
说明:遇到类似内存问题,猜测是同样的原因。测试中。。。
最近工作上一个模块内存泄露,内存缓慢增涨,存在oom的风险,很多人搞了一个月,最后定位是protobuf格式的数据的增涨。
首选说一下,我定位内存泄露采取的经验吧。我一般利用gperftools,在进程起来之后,在一个时刻,先dump一个内存占用的heap,然后压力一段时间,等内存有明显增涨后,在dump一个内存占用的heap,这样比较两个heap的占用,图形化成svg,这样就能看到那个函数,哪个数据结构占增涨的内存最多了。然后就可以去看代码了,看看是否是内存泄露了。
然后咱们说一下,为啥会定位到protobuf格式的数据的增涨。主要是protobuf的数组格式的数据(repeated类型)。对于这类数据,protobuf的内存管理,是采用跟string、vectror等数据结构类似的动态增涨的内存分配策略。简单来讲,比如开始这个数组为1,发现存不下了就会翻倍为2,再之后就4,依次类推(或者也有1.5倍的翻倍)。对这样的数据结构,clear并不会回收内存。那这样问题就来了,时间运行长之后,我们的数据结构就保留成最大的内存占用。其实如果只是单线程,且用到的这样的数据结构并不多的话,这样是没什么问题。但是如果这样的数据结构很多,且在多线程的环境中,着就会变得很糟,会产生隐身内存泄露的问题。
假设我们有1000个线程,没个线程有10000个这样的动态增长的数据结构。如果这个动态增长的数据结构变大1K,这样增加的内存为1K*1000*10000,约10g,这就很明显了。
那这样的问题咋解决呢?那就是我们使用string、vector、protobuf的时候,考虑每次使用完后就主动释放内存,每次用的时候重新进行创建,而不是一直使用clear函数。这样应该就能解决问题了。这样虽然会损失一定性能,但如果我们用上tcmalloc,损失的性能基本上可以被tcmalloc消化掉。
说明:遇到类似内存问题,猜测是同样的原因。测试中。。。
最近工作上一个模块内存泄露,内存缓慢增涨,存在oom的风险,很多人搞了一个月,最后定位是protobuf格式的数据的增涨。
首选说一下,我定位内存泄露采取的经验吧。我一般利用gperftools,在进程起来之后,在一个时刻,先dump一个内存占用的heap,然后压力一段时间,等内存有明显增涨后,在dump一个内存占用的heap,这样比较两个heap的占用,图形化成svg,这样就能看到那个函数,哪个数据结构占增涨的内存最多了。然后就可以去看代码了,看看是否是内存泄露了。
然后咱们说一下,为啥会定位到protobuf格式的数据的增涨。主要是protobuf的数组格式的数据(repeated类型)。对于这类数据,protobuf的内存管理,是采用跟string、vectror等数据结构类似的动态增涨的内存分配策略。简单来讲,比如开始这个数组为1,发现存不下了就会翻倍为2,再之后就4,依次类推(或者也有1.5倍的翻倍)。对这样的数据结构,clear并不会回收内存。那这样问题就来了,时间运行长之后,我们的数据结构就保留成最大的内存占用。其实如果只是单线程,且用到的这样的数据结构并不多的话,这样是没什么问题。但是如果这样的数据结构很多,且在多线程的环境中,着就会变得很糟,会产生隐身内存泄露的问题。
假设我们有1000个线程,没个线程有10000个这样的动态增长的数据结构。如果这个动态增长的数据结构变大1K,这样增加的内存为1K*1000*10000,约10g,这就很明显了。
那这样的问题咋解决呢?那就是我们使用string、vector、protobuf的时候,考虑每次使用完后就主动释放内存,每次用的时候重新进行创建,而不是一直使用clear函数。这样应该就能解决问题了。这样虽然会损失一定性能,但如果我们用上tcmalloc,损失的性能基本上可以被tcmalloc消化掉。
相关文章推荐
- 数据结构set string vector的使用
- VS环境下查内存泄露
- protobuf Message的序列化和反序列化string类型
- broadcom63283环境使用dmalloc调试内存泄露
- 跟着BOY 学习COCOS2D-X 网络篇---强联网(采用技术 BSD SOCKET+多线程技术 +protobuf)(环境搭建篇+服务器)
- 在多线程环境中不要使用string/wstring
- IE8 内存一直增长 内存泄露
- 使用reserve函数避免vector和string的内存重新分配
- MFC环境osgEarth开发程序内存泄露的解决办法
- J2ME String类型绘制字符串 为什么会造成内存泄露,终于弄懂了
- Delphi结构中使用String时遇到的内存泄露问题
- vector 内存泄露问题
- Protobuf 的 SerializeToString 的输入参数不是string
- gtest + protoBuf vs2010 win32 环境搭建(解决lib包冲突问题)
- 多线程内存泄露
- 多线程 DLL 回调函数问题,当应用程序退出时,有些操作并未完成,造成程序内存泄露,如何解决呢
- 介绍如何使用 POSIX 库在多线程环境中设计并发数据结构
- protobuf 协议 windows 下 java 环境搭建
- [置顶] 从零开始学C++之STL(二):实现简单容器模板类Vec(vector capacity 增长问题、allocator 内存分配器)
- 使用同步对象避免多线程退出时内存泄露