【转】警惕多线程环境string、vector、protobuf等自增长数据结构的隐性内存泄露
来源:互联网 发布:java 互联网金融项目 编辑:程序博客网 时间:2024/06/04 00:52
转载自 警惕多线程环境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消化掉。
- 【转】警惕多线程环境string、vector、protobuf等自增长数据结构的隐性内存泄露
- vector的自增长问题
- vector容器的自增长
- Vector的自增长方式
- vector容器的自增长
- C++ vector变量等导致内存泄露问题的解决方法
- 9.4 vector容器的自增长
- 顺序容器:vector的自增长特性
- 顺序容器:vector的自增长特性
- C++ vector容器的自增长
- C++中vector容器的自增长
- 警惕RXAndroid中的内存泄露
- 内存泄露,警惕构造函数中抛出的异常
- Net资源泄露(内存泄露,GDI泄露,handle 泄露等)的终极解决方案(转)
- vector内存增长方式
- vector内存增长方式
- vector调用push_back() 内存泄露的风险
- 【c++】vector.clear()的内存泄露问题
- bash: ./lmgrd: /lib/ld-lsb.so.3: bad ELF interpreter: 没有那个文件或目录
- 欢迎使用CSDN-markdown编辑器
- MySQL Binlog Mixed模式记录成Row格式
- 看侯俊杰讲多态的思考
- android studio如何配置环境变量并实现native方法
- 【转】警惕多线程环境string、vector、protobuf等自增长数据结构的隐性内存泄露
- Android开发获取通讯录
- 分享一个Struts2中Action工具类极大提高开发效率
- 数据库开发规范参考
- mysql如何卸载干净
- 使用C++语言读取*.mat文件中的数据 opencv matlab vs
- DevExpress和Winform基本操作
- linux常见指令以及权限理解
- 高性能JavaScript(您值得一看)