EasyDarwin开源流媒体服务器内存管理优化
—本文由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大小,基本不用考虑虚拟内存不够用的情况。
获取更多信息
Copyright © EasyDarwin.org 2012-2016

EasyDarwin开源流媒体服务器内存管理优化的更多相关文章
- EasyDarwin开源流媒体服务器gettimeofday性能优化(3000万/秒次优化至8000万次/秒)
-本文由EasyDarwin开源团队成员贡献 一.问题描述 Easydarwin中大量使用gettimeofday来获取系统时间,对系统性能造成了一定的影响.我们来做个测试: While(1) { G ...
- EasyDarwin开源流媒体服务器性能优化之Work-stealing优化方案
本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52400226 EasyDarwin团队的Ba ...
- EasyDarwin开源流媒体服务器实现RTSP直播同步输出MP4、RTMP、HLS的方案思路
背景 近期跟开源团队商量,想在EasyDarwin上继续做一些功能扩展,目前EasyDarwin开源流媒体服务器只能够实现高效的RTSP推流直播转发/分发功能,输入与输出都是RTSP/RTP流,不能够 ...
- EasyDarwin开源流媒体服务器将select改为epoll的方法
本文来自EasyDarwin团队Fantasy(fantasy(at)easydarwin.org) 一. EasyDarwin网络模型介绍 EventContext负责监听所有网络读写事件,Even ...
- NodeJS版本EasyDarwin开源流媒体服务器开发心得
title: Node版本EasyDarwin开发心得 date: 2018-03-27 22:46:15 tags: 年后着手Node版本EasyDarwin的开发工作,截止到今天2018年03月2 ...
- EasyDarwin开源流媒体服务器Golang版本:服务端录像功能发布
EasyDarwin开源流媒体服务器(www.easydarwin.org)现在使用Go版本实现了.最新的代码提交,已经支持了推流(或者拉流)的同时进行本地存储. 本地存储的原理,是在推流的同时启动f ...
- EasyDarwin开源流媒体服务器Golang版本:拉转推功能之拉流实现方法
EasyDarwin开源流媒体服务器(www.easydarwin.org),拉转推是一个很有意义的功能,它可将一个独立的RTSP数据源"拉"到服务器,再通过转发协议转发给多个客户 ...
- 解决用EasyDarwin开源流媒体服务器做HLS直播时Flash Player卡住的问题
最近在开发EasyDarwin开源流媒体服务器HLS直播的时候发现一个现象:在PC上用flash player播放HLS和在ios上面播放HLS时,效果明显不同,在ios上播放非常稳定,而在flash ...
- EasyDarwin开源流媒体服务器提供的TS切片/HLS直播打包库
EasyHLS Github:https://github.com/EasyDarwin/EasyHLS EasyHLS是什么? EasyHLS是EasyDarwin开源流媒体社区开发的一款HLS打 ...
随机推荐
- 【NOIP2016练习】T2 跑跑步 (数论)
: 这场的难度是从高到低的 ..]of longint; n,m,i,ans:longint; function gcd(x,y:longint):longint; var r:longint; be ...
- Yii关联查询(转载)
原文链接:http://keshion.iteye.com/blog/1607994 一.多表关联的配置 在我们使用 AR 执行关联查询之前,我们需要让 AR 知道一个 AR 类是怎样关联到另一个的. ...
- C#学习笔记---区分StringWriter(Reader)和StreamWriter(Reader),TextWriter(Reader),BinaryWriter(Reader)
1.TextWriter(Reader)分别是对连续字符系列处理的编写器(读写器),来自System.IO 2.StringWriter(Reader)继承TextWriter(Reader),它主要 ...
- js-数字渐增到指定的数字,在指定的时间内完成(有动画效果哦)插件jquery.animateNumber.js
本来在项目中我自己实现的效果是数字由0渐增到指定的数字就好. 但是,最终效果不理想! Why? 最终指定的数字太大了,TMMD,滚动好久就不到,那用户想看自己有多少钱了,那不是就一直等着!!!所以这个 ...
- R语言实战读书笔记(六)基本图形
#安装vcd包,数据集在vcd包中 library(vcd) counts <- table(Arthritis$Improved)counts # 垂直barplot(counts, main ...
- 同源策略Same-origin policy
同源策略Same-origin policy 同源策略Same-origin policy是Web应用的一种安全基础策略.它规定同一源中,页面包含的脚本可以访问该源下的其他页面的数据.只有当网址中的 ...
- Parallel Database for OLTP and OLAP
Parallel Database for OLTP and OLAP Just asurvey article on materials on parallel database products ...
- 好用的Python IDLE Sublime Text 3推荐
Sublime Text 3 下载地址为 LINK, Sublime Text 3 is currently in beta. The latest build is 3114. 参考的激活方式为输入 ...
- openfire Android学习(六)----总结
Xmpp的一些方法整理到一个工具类中了 XmppConnection.java [java] view plaincopy [java] view plaincopy import java.io.B ...
- cocos2d-x step by step(1) First Blood
下了cocos2d-x 源码,开搞! 首先,笔者本身 1) 5年没有摸过c++了 2) 没用过cocos2d-x 3) 有强烈的求知欲望(这条每个简历个人介绍不都这么写么, ...