—本文由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开源流媒体服务器内存管理优化相关推荐

  1. EasyDarwin开源流媒体服务器性能优化之Work-stealing优化方案

    本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52400226 EasyDarwin团队的Ba ...

  2. EasyDarwin开源流媒体服务器

    主要功能特点 基于Golang开发维护: 支持Windows.Linux.macOS平台: 支持RTSP推流分发(推模式转发): 支持RTSP拉流分发(拉模式转发): 服务端录像 参考:EasyDar ...

  3. EasyDarwin开源流媒体服务器Golang版本:拉转推功能之拉流实现方法

    EasyDarwin开源流媒体服务器(www.easydarwin.org),拉转推是一个很有意义的功能,它可将一个独立的RTSP数据源"拉"到服务器,再通过转发协议转发给多个客户 ...

  4. 多媒体视频开发_(6) EasyDarwin开源流媒体服务器程序搭建

    EasyDarwin开源流媒体服务器程序搭建 https://winqi.cn/120.html

  5. EasyDarwin开源流媒体服务器性能瓶颈分析及优化方案设计

    EasyDarwin现有架构介绍 EasyDarwin的现有架构对网络事件的处理是这样的,每一个Socket连接在EasyDarwin内部的对应存在形式就是一个Session,不论是RTSP服务对应的 ...

  6. EasyDarwin开源流媒体服务器进行RTSP转发过程中将sdp由文件存储改成内存索引

    -本篇由团队成员Fantasy供稿! 原始版本 在Darwin Streaming Server版本中,推送端DoAnnounce的时候后服务器会根据easydarwin.xml中配置的movies_ ...

  7. 基于EasyDarwin开源流媒体服务器框架实现EasyNVR H5无插件直播流媒体服务器方案

    背景分析 在之前的一篇博客<web无插件播放RTSP摄像机方案,拒绝插件,拥抱H5!>中,描述了实现一套H5无插件直播方案的各个组件的参考建议,又在博客<EasyNVR H5流媒体服 ...

  8. EasyPusher安卓直播推流到EasyDarwin开源流媒体服务器工程简析

    EasyPusher主要有三部分组件组成:采集,编码,叠加,上传.在这个基础上同时支持本地存储\后台预览的功能.主要业务模块与相关类之间的关系如图所示: Created with Raphaël 2. ...

  9. EasyDarwin开源流媒体服务器如何实现按需推送直播的

    --本文转自EasyDarwin开源团队成员邵帅的博客:http://blog.csdn.net/ss00_2012/article/details/51441753 我们使用EasyDarwin的推 ...

最新文章

  1. JavaSE入门学习51:多线程编程(二)
  2. Error:org.gradle.api.internal.changedetection.state.FileCollectionSnapshotImpl cannot be cast to org
  3. Tableau研学小课堂(part5)--参数
  4. 牛客小白月赛12 C 华华给月月出题 (积性函数,线性筛)
  5. 推荐系统可利用的特征
  6. Unity 找到隐藏的UGUI
  7. php无限评论回复_php实现无限级评论功能_后端开发
  8. 49.Linux/Unix 系统编程手册(下) -- 内存映射
  9. 【分布式事务系列二】Spring事务管理器PlatformTransactionManager
  10. science图表_如何利用PS制作统计图表(一些饼图的科学制作技巧)
  11. 网站logo服务器更换显示以前,网站更换logo
  12. mysql中null值求和_sql求和涉及到null值
  13. jav中spark迁移hive到mongo(更新数据)
  14. python儿童编程培训
  15. 旺谷图控与QT集成开发
  16. Git分支管理规范和解析
  17. JavaScript 数组头部、尾部进行增删元素
  18. android阿拉伯数字1 to一,英文数字的阿拉伯数字android
  19. Matlab多元非线性函数拟合
  20. autosar工具链

热门文章

  1. BZOJ1193 马步距离 (贪心)
  2. 使用 advanced installer 为 winform 做自动更新
  3. 数字模拟电路课程设计multisim仿真源文件和设计原理
  4. Qwt使用之QwtPlot
  5. 前端基础(二):HTML之列表、表格、表单标签
  6. java 降级_基于本地缓存的 fallback 降级机制
  7. 再见,Java 8!Java 17 发布,堪称史上最快的 JDK
  8. 侯耀文两女告侯耀华争遗产
  9. 人生苦短,饕餮docker
  10. Docker简介与安装