GLib中GThread Pool内存占用的问题
2017-03-20 11:12
295 查看
原始出处: http://blog.csdn.net/cool_way/article/details/8163967
按:一个思路,学习了。gstreamer也用了GLib库,收藏备用。
最近,我们发现有个简单的程序内存占用特别大,该程序自启动开始就占用着2.7G左右的内存。最初,大家都觉得不可思议,因为这个程序功能非常简单:
1)它采用多socket多线程的方式,即每个socket链接都是一个线程,但该线程的功能很简单,就是持续接收socket数据。2)程序的另外一个功能就是转发数据。我排查了程序各处代码,没有发现有申请大块内存的地方,即便socket接收所采用的buffer,也不到1KB。
那是什么东西吃掉了2.7G的内存?
(1)继续排查,因为我们采用了GLib库,所以此处暂且将线程变小。结果发现,内存占用小了很多。
(2)分别测试1,10,20,40,80个线程时,内存占用情况,发现每增加一个线程,基本上会增加9M内存左右。
(3)定位问题。从(2)可以看出,问题出在线程上,我首先想到应该是线程堆栈大小出了问题,于是做了一个简单的测试:使用ulimit -s查看到当前系统设置的堆栈大小为10240(即10M),那么当我通过ulimit -s 5120之后,发现那个简单程序占用内存将之了(按:应该是降至吧)1.3G。
OK,到这里问题就清楚了。GThread Pool在创建线程时,采用的是系统默认堆栈大小(如果需要设置堆栈大小,需要开启编译条件,并设置一个环境变量)。而不知道是谁设置了系统默认堆栈为10240,从而导致简单程序在多线程时内存占用巨大。
昨天写了更正此问题的方式(1.重新编译库。2.显示指定线程栈大小),但尝试之后发现在GThread Pool里都不可行。根据GThread Pool的官方说明:之所以每个线程都采用默认栈大小,是要解决多个Thread Pool公用线程的情况:如果线程的栈大小不一致,会导致无法在多个Thread Pool中被使用到。事实上,在GThread Pool代码中(glib-2.34.0),deprecated目录含有可指定堆栈大小的接口(gthread-deprecated.c),不过已被废弃。
目前我们的代码中,只采用了一个GThread Pool,所以不会出现多个Thread Pool共用线程的情况。即便如此,我也找不出方法去设置GThread Pool中线程的栈大小(要修改库代码的除外)。
官方还给出了一个可选择的方法,自己基于GAsyncQueue实现可指定堆栈大小的Thread Pool。这个办法略显繁琐,但也是一种可行的方式。当然,为了不修改库代码,需要在库上封装一层,以实现我们所需的可指定线程栈大小的Thread Pool。
按:一个思路,学习了。gstreamer也用了GLib库,收藏备用。
最近,我们发现有个简单的程序内存占用特别大,该程序自启动开始就占用着2.7G左右的内存。最初,大家都觉得不可思议,因为这个程序功能非常简单:
1)它采用多socket多线程的方式,即每个socket链接都是一个线程,但该线程的功能很简单,就是持续接收socket数据。2)程序的另外一个功能就是转发数据。我排查了程序各处代码,没有发现有申请大块内存的地方,即便socket接收所采用的buffer,也不到1KB。
那是什么东西吃掉了2.7G的内存?
(1)继续排查,因为我们采用了GLib库,所以此处暂且将线程变小。结果发现,内存占用小了很多。
(2)分别测试1,10,20,40,80个线程时,内存占用情况,发现每增加一个线程,基本上会增加9M内存左右。
(3)定位问题。从(2)可以看出,问题出在线程上,我首先想到应该是线程堆栈大小出了问题,于是做了一个简单的测试:使用ulimit -s查看到当前系统设置的堆栈大小为10240(即10M),那么当我通过ulimit -s 5120之后,发现那个简单程序占用内存将之了(按:应该是降至吧)1.3G。
OK,到这里问题就清楚了。GThread Pool在创建线程时,采用的是系统默认堆栈大小(如果需要设置堆栈大小,需要开启编译条件,并设置一个环境变量)。而不知道是谁设置了系统默认堆栈为10240,从而导致简单程序在多线程时内存占用巨大。
昨天写了更正此问题的方式(1.重新编译库。2.显示指定线程栈大小),但尝试之后发现在GThread Pool里都不可行。根据GThread Pool的官方说明:之所以每个线程都采用默认栈大小,是要解决多个Thread Pool公用线程的情况:如果线程的栈大小不一致,会导致无法在多个Thread Pool中被使用到。事实上,在GThread Pool代码中(glib-2.34.0),deprecated目录含有可指定堆栈大小的接口(gthread-deprecated.c),不过已被废弃。
目前我们的代码中,只采用了一个GThread Pool,所以不会出现多个Thread Pool共用线程的情况。即便如此,我也找不出方法去设置GThread Pool中线程的栈大小(要修改库代码的除外)。
官方还给出了一个可选择的方法,自己基于GAsyncQueue实现可指定堆栈大小的Thread Pool。这个办法略显繁琐,但也是一种可行的方式。当然,为了不修改库代码,需要在库上封装一层,以实现我们所需的可指定线程栈大小的Thread Pool。
相关文章推荐
- GLib中GThread Pool内存占用的问题
- C语言struct内存占用问题
- 结构体占用内存空间的问题
- CI框架在CLI下执行占用内存过大问题的解决方法
- 解决Window下MySql 5.6 安装后mysqld.exe内存占用很高的问题
- (转)Eclipse/CDT速度慢,占用内存大的问题的可用解决方案
- 使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题
- J2ME 内存占用的问题
- 解决IIS占用CPU和内存大的问题
- C++内存占用问题
- ASP+SQL查询查询问题--SQL占用很大内存?
- 解决w3wp.exe内存占用问题
- Windbg分析高内存占用问题
- 关于c++中map的内存占用问题
- 0324的学习笔记----里面最重要的就是一个tom猫的动画,和涉及到的内存问题(创建imageview的两种方式,imagenamed就会形成缓存,占用很多内
- 小白最快解决开发中mysql占用内存过高问题
- 对 SharedPreferences 的源码分析 : 提供简易的k v 的存储, 但SharedPreferences 系统机制也存在内存占用,全量写入的问题
- 关于MSSQL占用过多内存的问题
- [linux]服务器Cache占用过多内存导致系统内存不足问题的排查解决
- iOS的UIKit工程整合Cocos2d动画,内存占用过高的问题解决。