MAC内存泄漏的调试

2009-05-13 11:11:23来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

qiuhan
2007.12.7
现象:
对apache使用LoadRunner进行压力测试,使用top命令发现wired内存不断增长,导致
内存耗尽。(内存大小为512M)
分析:
我们从wired的内存的分配开始,自底向上开始分析。
首先,我们对wired内存的分配方式进行分类,内核中使用cnt.v_wire_count来统计wired页面数量,
atomic_add_int(&cnt.v_wire_count, 1);
是增加wired页面(调用函数有vm_page_alloc vm_page_wire)
atomic_subtract_int(&cnt.v_wire_count, 1);
是减少wired页面(调用函数有_pmap_unwire_pte_hold pmap_release vm_page_unwire)
我们觉得vm_page_wire过于泛泛,再对调用vm_page_wire的函数进行分类,有
socow_setup, do_sendfile, allocbuf, vm_fault, vm_thread_swapin, vm_page_grab
因此加上vm_page_alloc分成7类,用数组wired_page_cnt来分别表示每一类的wired页面数.
在struct vm_page中加入int type;来区分不同类别,在增加wired页面时对type进行赋值,
并以type值为下标增加wired_page_cnt数组中对应的元素;在减少wired页面时也以type为
下标减少wired_page_cnt数组中对应的元素。
为了便于查看,我们增加了一个ddb的show wired命令来查看数组中的元素:
DB_SHOW_COMMAND(wired, vm_page_print_wired_info)
我们用修改后的内核进行压力测试,当top显示wired为117M时,进行查看:
db> show wired
socow_setup: 0
do_sendfile: 0
allocbuf: 351
vm_fault: 486
vm_thread_swapin: 0
vm_page_grab: 0
vm_page_alloc: 29150
db> show page
...
cnt.v_wire_count: 29987
...
我们发现show wired显示值之和刚好为cnt.v_wire_count的值,证明我们的代码无误。
另一方面,我们粗略计算一下29987*4k大小刚好差不多为117M
另外,令我们感兴趣的是vm_page_alloc的值最大,而且随着wired内存的增加,仅
vm_page_alloc的数值增加,其它基本不动。从这里来看,我们先前对vm_page_wire
进行的分类是不必要的。下面我们要关注的就是vm_page_alloc
调用vm_page_alloc的有pmap_pinit,vm_fault等17个函数,我们仍然按照先前的思路,
分别统计这些函数对wired页面的贡献。我们也增加一个ddb的命令show alloc来查看。
重新用新内核进行压力测试,当wired内存为128M时:
db> show alloc
pmap_pinit: 196
_pmap_allocpte: 975
pmap_growkernel: 61
allocbuf: 14932
obj_alloc: 2163
kmem_malloc: 13165
vm_page_grab: 520
total wired: 32013
等待wired内存增加约1M(使用top):
db> show alloc
pmap_pinit: 196
_pmap_allocpte: 975
pmap_growkernel: 61
allocbuf: 14932
obj_alloc: 2163
kmem_malloc: 13560
vm_page_grab: 520
total wired: 32408
我们发现仅有kmem_malloc的值在增加。注意:
1 为了清晰,我们打印时忽略了小于5的项目
2 我们关注的是增长趋势,而不是大小
3 实际分析时,开始时allocbuf增长最快,但后来基本不增加反而下降了
调用kmem_malloc仅有page_alloc(我们没有编译memguard_alloc),这是一个好消息,
但随之我们却发现一个坏消息:调用page_alloc的地方会很分散。因为存在:
keg->uk_allocf = page_alloc;
这时,我们才意识到这种分析方法有着明显的缺陷:
1 调用的函数不能太多,而且对于通过指针调用的方式不太适合
2 每一层的推进都需要比较多的编码,而且都需要通过增加参数或者标志位来区分

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:sysctl分析

下一篇:Dedecms之PHP环境搭建简易教程