GLib中GThread Pool内存占用的问题
来源:互联网 发布:淘宝商城推广培训 编辑:程序博客网 时间:2024/05/16 13:48
最近,我们发现有个简单的程序内存占用特别大,该程序自启动开始就占用着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内存占用的问题
- GLib中GThread Pool内存占用的问题
- 关于c++中map的内存占用问题
- 关于c++中map的内存占用问题
- J2ME 内存占用的问题
- J2ME 内存占用的问题
- C#占用内存的问题
- ERROR: glib-2.22 gthread-2.0 is required to compile QEMU
- [J2ME]Enumeration的内存占用问题
- 关于占用过多内存的问题
- 关于MSSQL占用过多内存的问题
- 关于MSSQL占用过多内存的问题
- 正确理解Linux内存占用过高的问题
- Image对象的内存占用问题。
- 正确理解Linux内存占用过高的问题
- hiveserver 占用内存过大的问题
- 正确理解Linux内存占用过高的问题
- Android 要注意的内存占用问题
- 编译的四个过程
- myeclipse中反编译class文件插件的安装问题
- U盘硬件根底&& DOS下磁盘软件&USB2.0驱动
- linux下umount 提示“device busy\"解决方法
- JavaSE第三讲:原生数据类型使用陷阱 Ptifall of Primitive Data Type
- GLib中GThread Pool内存占用的问题
- 【Objective-C】单例模式的实现
- [shell应用进阶]:限制同时运行脚本实例的个数 -- 串行化:换一个思路。
- .net框架
- Linux硬件查看命令
- 桥接:实现windows与linux文件共享
- maven中properties标签定义变量
- CentOS初体验
- 博客搬家