EasyDarwin开源流媒体服务器内存管理优化
来源:互联网 发布:剑灵女生捏脸数据 编辑:程序博客网 时间:2024/05/17 01:09
—本文由EasyDarwin开源团队成员Fantasy贡献
前言
最近在linux上跑EasyDarwin发现一个很奇怪的问题,当有RTSPSession连接上来的时候,发现进程的虚拟内存映射一下就多了64M,如下图:
备注:anon标识堆内存
过程
把通过在代码里面加system(“pmap pid”)命令,一步步跟,最终确定到是在NEW RTSPSession的时候多出来的64M内存,反复review代码,发现RTSPSession类并没有申请这么大的堆内存,把整个类大小输出,也远没有这么大。表示很奇怪。
决定写一些简单的类,一个个继承RTSPSession继承过的那些类,然后在NEW RTSPSession前面new一个对象,发现就会在NEW RTSPSession之前就多出来64M内存,果真是继承的类有申请大块内存?再次review,还是没有发现。
不继承任何类,new一个对象试试,结果还是多出来了。
查阅资料,发现是glibc 的malloc捣的鬼,glibc为了分配内存的性能的问题,使用了很多叫做arena的memory pool,缺省配置在64bit下面是每一个arena为64M,一个进程可以最多有 cores * 8个arena。假设你的机器是4核的,那么最多可以有4 * 8 = 32个arena,也就是使用32 * 64 = 2048M内存。 当然你也可以通过设置环境变量来改变arena的数量.例如export MALLOC_ARENA_MAX=1
分析
我们先分析下进程内存结构:
每个进程有一个堆空间,glibc为了防止线程之间存在内存分配竞争问题,采用了预先分配的方式来解决问题,即便你malloc 1个自己也给你先分个64M虚拟内存,注意这里是虚拟内存,不是物理内存。
测试代码如下:
#include <stdio.h>#include "tcmalloc.h"#include <pthread.h>#include <unistd.h>#include <stdlib.h>#include <iostream>using namespace std;volatile bool start = 0;void *threadFunc(void *argv){ int pid = getpid(); char cmdstr[64] = {0}; sprintf(cmdstr,"pmap %d|grep total",pid); while(1) { //if(start) { char *a = (char*)malloc(1024); printf("thread malloc\n"); system(cmdstr); //sleep(1); start = 0; } sleep(1); }}int main(){ //char *a = (char*)tc_malloc(100); pthread_t pornsaveId; int ret = 0; ret = pthread_create(&pornsaveId, NULL, threadFunc,NULL); if (ret) { return 0; } //tc_free(a); while(getchar()) { c->score = 1000; start = 1; } return 0;}
优化建议
Google开发了一个内存管理库,perftool,其中实现和tcmalloc和jemalloc,效率要比glibc高得多,具体实现细节可以自行百度。
当通过perf工具发现大量的malloc和free的时候,可以考虑引入google的tcmalloc或者jemalloc来解决性能问题。顺便说一句,尽量少在线程池中频繁进行申请和释放内存的操作,对性能影响比较大,因为线程之间存在竞争关系。
tcmalloc使用例子
先上网下载perftool库,编译:
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include "tcmalloc.h"using namespace std;volatile bool start = 0;void* thread_run( void* ){ while ( 1 ) { if ( start ) { cout << "Thread malloc" << endl; char *buf = (char *)tc_malloc(1024);// char[1024]; start = 0; } sleep( 1 ); }}int main(){ pthread_t th; printf("wait input 111\n"); getchar(); printf("wait input 222\n"); getchar(); printf("wait input 333\n"); pthread_create( &th, 0, thread_run, 0 ); while ( (getchar() ) ) { start = 1; } return(0);}
运行后发现,没有再像glibc那样有大块映射的虚拟内存了,而且性能也提高了很多(可以写个死循环进行测试,对比调用次数)
备注:现在机器基本都是64位的,虚拟内存2^64大小,基本不用考虑虚拟内存不够用的情况。
获取更多信息
邮件:support@easydarwin.org
WEB:www.EasyDarwin.org
Copyright © EasyDarwin.org 2012-2016
- EasyDarwin开源流媒体服务器内存管理优化
- [转载]EasyDarwin开源流媒体服务器内存管理优化
- 开源流媒体服务器--EasyDarwin
- EasyDarwin开源流媒体服务器Work-stealing优化方案
- EasyDarwin开源流媒体服务器性能优化之Work-stealing优化方案
- EasyDarwin开源流媒体服务器性能瓶颈分析及优化方案设计
- EasyDarwin开源流媒体服务器性能瓶颈分析及优化方案设计
- EasyDarwin开源流媒体服务器性能瓶颈分析及优化方案设计
- EasyDarwin开源流媒体服务器进行RTSP转发过程中将sdp由文件存储改成内存索引
- EasyDarwin开源流媒体服务器进行RTSP转发过程中将sdp由文件存储改成内存索引
- EasyDarwin开源流媒体项目
- vs2015编译EasyDarwin开源流媒体服务器Linux版本调研
- vs2015编译EasyDarwin开源流媒体服务器Linux版本调研
- EasyDarwin开源流媒体服务器gettimeofday性能优化(3000万/秒次优化至8000万次/秒)
- [转载]EasyDarwin开源流媒体服务器gettimeofday性能优化(3000万/秒次优化至8000万次/秒)
- EasyDarwin开源流媒体社区视频教程
- 开源流媒体服务器
- 开源流媒体服务器EasyDarwin支持epoll网络模型,大大提升流媒体服务器网络并发性能
- 字体对话框(fontDialog控件)
- IM项目进程总结
- npm介绍与cnpm介绍
- 二叉树、二叉链表
- Windows游戏编程大师技巧之三角形填充
- EasyDarwin开源流媒体服务器内存管理优化
- 数组去除重复的数
- php 基础知识点梳理
- pascals-triangle,pascals-triangle-ii
- 初创公司如何招聘技术人员
- Linux 关机命令
- @+id/和@id的区别
- caffe源码分析 vector<Blob<Dtype>*>& bottom
- 蓝牙BLE ATT剖析(二)-- PDU