注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

生命无非记忆

不要在记忆中丢失了自己

 
 
 

日志

 
 

使用malloc_stats发现内存占用过高问题  

2015-12-10 11:18:12|  分类: linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
系统内存占用过高主要有两种可能:一种内存泄露,二是由于malloc内存管理算法导致已经free的内存没有还给操作系统(参考http://zisedeqing.blog.163.com/blog/static/9555087120151182656875/)。
glibc提供了两个用来监控malloc内存状态的接口:malloc_stats 和mallinfo
malloc_stats 主要是把每个area请求和正在使用的内存状态输出到标准错误输出,malloc_statas详细说明参见:http://www.man7.org/linux/man-pages/man3/malloc_stats.3.html
mallinfo:主要是输出主area的内存详细信息,参考链接:http://www.man7.org/linux/man-pages/man3/mallinfo.3.html
主要说明一下mallinfo的返回结构:
struct mallinfo {
int arena; /* Non-mmapped space allocated (bytes) */
int ordblks; /* Number of free chunks */
int smblks; /* Number of free fastbin blocks */
int hblks; /* Number of mmapped regions */
int hblkhd; /* Space allocated in mmapped regions (bytes) */
int usmblks; /* Maximum total allocated space (bytes) */
int fsmblks; /* Space in freed fastbin blocks (bytes) */
int uordblks; /* Total allocated space (bytes) */
int fordblks; /* Total free space (bytes) */
int keepcost; /* Top-most, releasable space (bytes) */
};
arena:表示主的area持有的内存总量,这些内存不包括使用mmap分配的内存
ordblks:表示已经free掉的内存chunks的个数
fordblks:与ordblks对应,表示已经free掉的内存总量
smblks:fastbin的内存块个数,这些也是已经被free的内存
fsmblks:与smblks对应,表示fastbin的内存总量
hblks:mmap的个数
hblkhd:与hblks对应,持有的使用mmap分配的内存总量
uordblks:表示area已经分配出去的内存总量,也就是进程没有free的内存
arena = fordblks + uordblks
fordblks表示的内存就是我们已经free掉,但是malloc并没有还给os的内存,这些内存依然为进程持有,如果后续还有内存申请,那么这些内存是可以重用的。

malloc_stats的输出格式为:
Arena 0:
system bytes     =     397312    // 这个就是对mallinfo的arena
in use bytes     =     395584     //  这个就是对mallinfo的uordblks
Total (incl. mmap):
system bytes     = 1479462912  // 这个表示整个进程持有的内存总量,包含mmap分配的内存
in use bytes     = 1122800288   // 这个表示整个进程正在使用的内存总量,包含mmap分配的内存
max mmap regions =         32
max mmap bytes   = 1189548032 // 进程使用mmap分配的内存

对于单个的area,malloc_stats输出的没有mallinfo多,如果需要使用malloc_stats输出每个area的详细信息,则需要自己修改glibc的源码,编译以后,使用http://zisedeqing.blog.163.com/blog/static/95550871201511841011574/中介绍的方法替换glibc为我们自己编译的glibc即可

下面举个例子说明一下:

#include <malloc.h>

int
main(void)
{
int i = 0;
int *arr[1000000];
int len = 0;

for (i = 0; i < 1000000;i++)
{
srand(time(NULL)+ i);
len = random()%(52*1024);
arr[i] = (int*)malloc(len);
}

printf("before free:\n");
malloc_stats();

for(i = 0; i < 1000000-1;i++)
free(arr[i]);

printf("after free:\n");
malloc_stats();

free(arr[1000000-1]);
printf("after free the last one\n");
malloc_stats();
return 0;
}

该程序执行后的输出如下:

before free:
Arena 0:
system bytes = 877121536
in use bytes = 877086528
ordblks:1, smblks:0, hblks:0, hblkhd:0, usmblks:0, fsmblks:0, fordblks:35008, keepcost:35008
Total (incl. mmap):
system bytes = 877121536
in use bytes = 877086528
max mmap regions = 0
max mmap bytes = 0
after free:
Arena 0:
system bytes = 877121536
in use bytes = 24624
ordblks:2, smblks:0, hblks:0, hblkhd:0, usmblks:0, fsmblks:0, fordblks:877096912, keepcost:35008
Total (incl. mmap):
system bytes = 877121536
in use bytes = 24624
max mmap regions = 0
max mmap bytes = 0
after free the last one
Arena 0:
system bytes = 135168
in use bytes = 0
ordblks:1, smblks:0, hblks:0, hblkhd:0, usmblks:0, fsmblks:0, fordblks:135168, keepcost:135168
Total (incl. mmap):
system bytes = 135168
in use bytes = 0
max mmap regions = 0
max mmap bytes = 0

从上面可以看出在第一次free时,整个系统依然持有我们之前申请的所有内存,而在我们释放掉最后的一个内存时,malloc基本把我们之前申请的内存全部返还给了操作系统。

上面的输出是我修改glibc后的结果,比原始的glibc多了每个area的详细信息,如ordblks:1, smblks:0, hblks:0, hblkhd:0, usmblks:0, fsmblks:0, fordblks:135168, keepcost:135168。

  评论这张
 
阅读(301)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017