一个内存问题

一个内存问题

现象

最近发现有一个python程序,在top的%VSZ显示中占用率很高,但是使用gc.garbage查看并没有发现有不可达的对象。

for c in threading.enumerate():
	syslog(LOG_DEBUG, 'FFF> %s' % str(c))
rt = gc.collect()
syslog(LOG_DEBUG, "%d unreachable" % rt)
garbages = gc.garbage
syslog(LOG_DEBUG, "\n%d garbages:" % len(garbages))
for garbage in garbages:
	syslog(LOG_DEBUG, "%s" % str(garbage))

Mem: 101988K used, 24272K free, 0K shrd, 0K buff, 41376K cached
CPU:   8% usr  75% sys   0% nic   0% idle   0% io   0% irq  16% sirq
Load average: 1.54 1.46 1.56 2/88 19505
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
 1944     1 root     S <   8940   7%  17% /usr/sbin/ok_capwapc
 2015     1 root     S     1556   1%   8% {supervisor.sh} /bin/sh /lib/okos/sup
19328   758 root     R     1552   1%   8% top
 1954     1 nobody   S     1004   1%   8% /usr/sbin/dnsmasq -C /var/etc/dnsmasq
    3     2 root     RW       0   0%   8% [ksoftirqd/0]
 5396     1 root     S <  50264  40%   0% /usr/bin/wifidog -s -d 60        #### 40% too high
  601     1 root     S    37316  30%   0% {clientevent.py} /usr/bin/python /lib #### 30% too high
 5087     1 root     S <   5480   4%   0% /usr/sbin/arpwatch -f /tmp/arpwatch/a
 5099     1 root     S <   5480   4%   0% /usr/sbin/arpwatch -f /tmp/arpwatch/a
 5107     1 root     S <   5480   4%   0% /usr/sbin/arpwatch -f /tmp/arpwatch/a
 5117     1 root     S <   5480   4%   0% /usr/sbin/arpwatch -f /tmp/arpwatch/a
  824     1 root     S     2432   2%   0% hostapd -g /var/run/hostapd/global -B
 6664     1 root     S     1676   1%   0% /sbin/syslogd -L -R log.networkworld3
 3442     1 root     S <   1588   1%   0% hostapd_cli -p /var/run/hostapd-wifi1
 3263     1 root     S <   1588   1%   0% hostapd_cli -p /var/run/hostapd-wifi1
 3366     1 root     S <   1588   1%   0% hostapd_cli -p /var/run/hostapd-wifi1
 4347     1 root     S <   1588   1%   0% hostapd_cli -p /var/run/hostapd-wifi0
 3632     1 root     S <   1588   1%   0% hostapd_cli -p /var/run/hostapd-wifi1
 3519     1 root     S <   1588   1%   0% hostapd_cli -p /var/run/hostapd-wifi1
^C762     1 root     S <   1588   1%   0% hostapd_cli -p /var/run/hostapd-wifi1

查看/proc/601下的具体maps情况

oot@DESK /proc/601 [#]# cat maps
00400000-0051e000 r-xp 00000000 00:01 86         /usr/bin/python2.7
0052d000-0052e000 r--p 0011d000 00:01 86         /usr/bin/python2.7
0052e000-00558000 rw-p 0011e000 00:01 86         /usr/bin/python2.7
00558000-00561000 rwxp 00000000 00:00 0 
00661000-007a0000 rwxp 00000000 00:00 0          [heap]
1. 
751fd000-751fe000 ---p 00000000 00:00 0 # 0x0000_1000 4K
751fe000-753fd000 rw-p 00000000 00:00 0 # 0x0020_0000 2M
2. 
753fd000-753fe000 ---p 00000000 00:00 0 # 0x0000_1000 4k
753fe000-755fd000 rw-p 00000000 00:00 0 # 0x0020_0000 2M
3. 
755fd000-755fe000 ---p 00000000 00:00 0 
755fe000-757fd000 rw-p 00000000 00:00 0
4. 
757fd000-757fe000 ---p 00000000 00:00 0 
757fe000-759fd000 rw-p 00000000 00:00 0
5. 
759fd000-759fe000 ---p 00000000 00:00 0 
759fe000-75bfd000 rw-p 00000000 00:00 0 
6. 
75bfd000-75bfe000 ---p 00000000 00:00 0 
75bfe000-75dfd000 rw-p 00000000 00:00 0 
7. 
75dfd000-75dfe000 ---p 00000000 00:00 0 
75dfe000-75ffd000 rw-p 00000000 00:00 0 
8. 
75ffd000-75ffe000 ---p 00000000 00:00 0 
75ffe000-761fd000 rw-p 00000000 00:00 0 
9. 
761fd000-761fe000 ---p 00000000 00:00 0 
761fe000-763fd000 rw-p 00000000 00:00 0 
10. 
763fd000-763fe000 ---p 00000000 00:00 0 
763fe000-765fd000 rw-p 00000000 00:00 0 
11. 
765fd000-765fe000 ---p 00000000 00:00 0 
765fe000-767fd000 rw-p 00000000 00:00 0 
12. 
767fd000-767fe000 ---p 00000000 00:00 0 
767fe000-769fd000 rw-p 00000000 00:00 0 
13. 
769fd000-769fe000 ---p 00000000 00:00 0 
769fe000-76bfd000 rw-p 00000000 00:00 0 

76bfd000-76c9f000 rw-p 00000000 00:00 0 # 0x000A_2000 648K

76cb7000-76cb9000 r-xp 00000000 00:01 581        /usr/lib/python2.7/lib-dynload/syslog.so
76cb9000-76cc8000 ---p 00000000 00:00 0 
76cc8000-76cc9000 r--p 00001000 00:01 581        /usr/lib/python2.7/lib-dynload/syslog.so
76cc9000-76cca000 rw-p 00002000 00:01 581        /usr/lib/python2.7/lib-dynload/syslog.so
76cca000-76d0b000 rw-p 00000000 00:00 0 
76d0b000-76d0f000 r-xp 00000000 00:01 580        /usr/lib/python2.7/lib-dynload/select.so
76d0f000-76d1e000 ---p 00000000 00:00 0 
76d1e000-76d1f000 r--p 00003000 00:01 580        /usr/lib/python2.7/lib-dynload/select.so
76d1f000-76d21000 rw-p 00004000 00:01 580        /usr/lib/python2.7/lib-dynload/select.so
76d21000-76d25000 r-xp 00000000 00:01 570        /usr/lib/python2.7/lib-dynload/strop.so
76d25000-76d34000 ---p 00000000 00:00 0 
76d34000-76d35000 r--p 00003000 00:01 570        /usr/lib/python2.7/lib-dynload/strop.so
76d35000-76d37000 rw-p 00004000 00:01 570        /usr/lib/python2.7/lib-dynload/strop.so
76d37000-76d78000 rw-p 00000000 00:00 0 
76d78000-76d7a000 r-xp 00000000 00:01 584        /usr/lib/python2.7/lib-dynload/fcntl.so
76d7a000-76d89000 ---p 00000000 00:00 0 
76d89000-76d8a000 r--p 00001000 00:01 584        /usr/lib/python2.7/lib-dynload/fcntl.so
76d8a000-76d8b000 rw-p 00002000 00:01 584        /usr/lib/python2.7/lib-dynload/fcntl.so
76d8b000-76d8e000 r-xp 00000000 00:01 542        /usr/lib/python2.7/lib-dynload/_random.so
76d8e000-76d9d000 ---p 00000000 00:00 0 
76d9d000-76d9e000 r--p 00002000 00:01 542        /usr/lib/python2.7/lib-dynload/_random.so
76d9e000-76d9f000 rw-p 00003000 00:01 542        /usr/lib/python2.7/lib-dynload/_random.so
76d9f000-76da7000 r-xp 00000000 00:01 575        /usr/lib/python2.7/lib-dynload/math.so
76da7000-76db6000 ---p 00000000 00:00 0 
76db6000-76db7000 r--p 00007000 00:01 575        /usr/lib/python2.7/lib-dynload/math.so
76db7000-76db8000 rw-p 00008000 00:01 575        /usr/lib/python2.7/lib-dynload/math.so
76db8000-76dbb000 r-xp 00000000 00:01 577        /usr/lib/python2.7/lib-dynload/_heapq.so
76dbb000-76dca000 ---p 00000000 00:00 0 
76dca000-76dcb000 r--p 00002000 00:01 577        /usr/lib/python2.7/lib-dynload/_heapq.so
76dcb000-76dcd000 rw-p 00003000 00:01 577        /usr/lib/python2.7/lib-dynload/_heapq.so
76dcd000-76dcf000 r-xp 00000000 00:01 585        /usr/lib/python2.7/lib-dynload/_bisect.so
76dcf000-76dde000 ---p 00000000 00:00 0 
76dde000-76ddf000 r--p 00001000 00:01 585        /usr/lib/python2.7/lib-dynload/_bisect.so
76ddf000-76de0000 rw-p 00002000 00:01 585        /usr/lib/python2.7/lib-dynload/_bisect.so
76de0000-76de9000 r-xp 00000000 00:01 563        /usr/lib/python2.7/lib-d       ynload/itertools.so
76de9000-76df8000 ---p 00000000 00:00 0 
76df8000-76df9000 r--p 00008000 00:01 563        /usr/lib/python2.7/lib-dynload/itertools.so
76df9000-76dfc000 rw-p 00009000 00:01 563        /usr/lib/python2.7/lib-dynload/itertools.so
76dfc000-76e02000 r-xp 00000000 00:01 571        /usr/lib/python2.7/lib-dynload/operator.so
76e02000-76e11000 ---p 00000000 00:00 0 
76e11000-76e12000 r--p 00005000 00:01 571        /usr/lib/python2.7/lib-dynload/operator.so
76e12000-76e13000 rw-p 00006000 00:01 571        /usr/lib/python2.7/lib-dynload/operator.so
76e13000-76e18000 r-xp 00000000 00:01 576        /usr/lib/python2.7/lib-dynload/_collections.so
76e18000-76e27000 ---p 00000000 00:00 0 
76e27000-76e28000 r--p 00004000 00:01 576        /usr/lib/python2.7/lib-dynload/_collections.so
76e28000-76e29000 rw-p 00005000 00:01 576        /usr/lib/python2.7/lib-dynload/_collections.so
76e29000-76e2c000 r-xp 00000000 00:01 540        /usr/lib/python2.7/lib-dynload/cStringIO.so
76e2c000-76e3b000 ---p 00000000 00:00 0 
76e3b000-76e3c000 r--p 00002000 00:01 540        /usr/lib/python2.7/lib-dynload/cStringIO.so
76e3c000-76e3d000 rw-p 00003000 00:01 540        /usr/lib/python2.7/lib-dynload/cStringIO.so
76e3d000-76f5e000 r-xp 00000000 00:01 1192       /usr/lib/libcrypto.so.1.0.0
76f5e000-76f6e000 ---p 00000000 00:00 0 
76f6e000-76f7a000 r--p 00121000 00:01 1192       /usr/lib/libcrypto.so.1.0.0
76f7a000-76f7f000 rw-p 0012d000 00:01 1192       /usr/lib/libcrypto.so.1.0.0
76f7f000-76f80000 rw-p 00000000 00:00 0 
76f80000-76fc6000 r-xp 00000000 00:01 1227       /usr/lib/libssl.so.1.0.0
76fc6000-76fd5000 ---p 00000000 00:00 0 
76fd5000-76fd7000 r--p 00045000 00:01 1227       /usr/lib/libssl.so.1.0.0
76fd7000-76fd9000 rw-p 00047000 00:01 1227       /usr/lib/libssl.so.1.0.0
76fd9000-76fe0000 r-xp 00000000 00:01 572        /usr/lib/python2.7/lib-dynload/_ssl.so
76fe0000-76fef000 ---p 00000000 00:00 0 
76fef000-76ff0000 r--p 00006000 00:01 572        /usr/lib/python2.7/lib-dynload/_ssl.so
76ff0000-76ff1000 rw-p 00007000 00:01 572        /usr/lib/python2.7/lib-dynload/_ssl.so
76ff1000-76ff3000 r-xp 00000000 00:01 583        /usr/lib/python2.7/lib-dynload/_functools.so
76ff3000-77002000 ---p 00000000 00:00 0 
77002000-77003000 r--p 00001000 00:01 583        /usr/lib/python2.7/lib-dynload/_functools.so
77003000-77004000 rw-p 00002000 00:01 583        /usr/lib/python2.7/lib-dynload/_functools.so
77004000-7700f000 r-xp 00000000 00:01 558        /usr/lib/python2.7/lib-dynload/_socket.so
7700f000-7701e000 ---p 00000000 00:00 0 
7701e000-7701f000 r--p 0000a000 00:01 558        /usr/lib/python2.7/lib-dynload/_socket.so
7701f000-77022000 rw-p 0000b000 00:01 558        /usr/lib/python2.7/lib-dynload/_socket.so
77022000-770e5000 rw-p 00000000 00:00 0 
770f6000-770fd000 r-xp 00000000 00:01 582        /usr/lib/python2.7/lib-dynload/array.so
770fd000-7710c000 ---p 00000000 00:00 0 
7710c000-7710d000 r--p 00006000 00:01 582        /usr/lib/python2.7/lib-dynload/array.so
7710d000-7710f000 rw-p 00007000 00:01 582        /usr/lib/python2.7/lib-dynload/array.so
7710f000-77118000 r-xp 00000000 00:01 565        /usr/lib/python2.7/lib-dynload/_sha512.so
77118000-77127000 ---p 00000000 00:00 0 
77127000-77128000 r--p 00008000 00:01 565        /usr/lib/python2.7/lib-dynload/_sha512.so
77128000-77129000 rw-p 00009000 00:01 565        /usr/lib/python2.7/lib-dynload/_sha512.so
77129000-7712d000 r-xp 00000000 00:01 533        /usr/lib/python2.7/lib-dynload/_sha256.so
7712d000-7713c000 ---p 00000000 00:00 0 
7713c000-7713d000 r--p 00003000 00:01 533        /usr/lib/python2.7/lib-dynload/_sha256.so
7713d000-7713e000 rw-p 00004000 00:01 533        /usr/lib/python2.7/lib-dynload/_sha256.so
7713e000-77141000 r-xp 00000000 00:01 551        /usr/lib/python2.7/lib-dynload/_sha.so
77141000-77150000 ---p 00000000 00:00 0 
77150000-77151000 r--p 00002000 00:01 551        /usr/lib/python2.7/lib-dynload/_sha.so
77151000-77152000 rw-p 00003000 00:01 551        /usr/lib/python2.7/lib-dynload/_sha.so
77152000-77156000 r-xp 00000000 00:01 586        /usr/lib/python2.7/lib-dynload/binascii.so
77156000-77165000 ---p 00000000 00:00 0 
77165000-77166000 r--p 00003000 00:01 586        /usr/lib/python2.7/lib-dynload/binascii.so
77166000-77167000 rw-p 00004000 00:01 586        /usr/lib/python2.7/lib-dynload/binascii.so
77167000-771a8000 rw-p 00000000 00:00 0 
771a8000-771aa000 r-xp 00000000 00:01 545        /usr/lib/python2.7/lib-dynload/_md5.so
771aa000-771b9000 ---p 00000000 00:00 0 
771b9000-771ba000 r--p 00001000 00:01 545        /usr/lib/python2.7/lib-dynload/_md5.so
771ba000-771bb000 rw-p 00002000 00:01 545        /usr/lib/python2.7/lib-dynload/_md5.so
771bb000-771c1000 r-xp 00000000 00:01 567        /usr/lib/python2.7/lib-dynload/_struct.so
771c1000-771d0000 ---p 00000000 00:00 0 
771d0000-771d1000 r--p 00005000 00:01 567        /usr/lib/python2.7/lib-dynload/_struct.so
771d1000-771d3000 rw-p 00006000 00:01 567        /usr/lib/python2.7/lib-dynload/_struct.so
771d3000-771d6000 r-xp 00000000 00:01 561        /usr/lib/python2.7/lib-dynload/time.so
771d6000-771e5000 ---p 00000000 00:00 0 
771e5000-771e6000 r--p 00002000 00:01 561        /usr/lib/python2.7/lib-dynload/time.so
771e6000-771e8000 rw-p 00003000 00:01 561        /usr/lib/python2.7/lib-dynload/time.so
771e9000-772ac000 rw-p 00000000 00:00 0 
772ac000-77305000 r-xp 00000000 00:01 1490       /lib/libuClibc-0.9.33.2.so
77305000-77314000 ---p 00000000 00:00 0 
77314000-77315000 r--p 00058000 00:01 1490       /lib/libuClibc-0.9.33.2.so
77315000-77316000 rw-p 00059000 00:01 1490       /lib/libuClibc-0.9.33.2.so
77316000-7731b000 rw-p 00000000 00:00 0 
7731b000-7732e000 r-xp 00000000 00:01 1544       /lib/libgcc_s.so.1
7732e000-7733d000 ---p 00000000 00:00 0 
7733d000-7733e000 r--p 00012000 00:01 1544       /lib/libgcc_s.so.1
7733e000-7733f000 rw-p 00013000 00:01 1544       /lib/libgcc_s.so.1
7733f000-77356000 r-xp 00000000 00:01 1501       /lib/libm-0.9.33.2.so
77356000-77365000 ---p 00000000 00:00 0 
77365000-77366000 rw-p 00016000 00:01 1501       /lib/libm-0.9.33.2.so
77366000-77378000 r-xp 00000000 00:01 1163       /usr/lib/libz.so.1.2.7
77378000-77387000 ---p 00000000 00:00 0 
77387000-77388000 r--p 00011000 00:01 1163       /usr/lib/libz.so.1.2.7
77388000-77389000 rw-p 00012000 00:01 1163       /usr/lib/libz.so.1.2.7
77389000-7738b000 r-xp 00000000 00:01 1545       /lib/libutil-0.9.33.2.so
7738b000-7739a000 ---p 00000000 00:00 0 
7739a000-7739b000 rw-p 00001000 00:01 1545       /lib/libutil-0.9.33.2.so
7739b000-7739e000 r-xp 00000000 00:01 1503       /lib/libdl-0.9.33.2.so
7739e000-773ad000 ---p 00000000 00:00 0 
773ad000-773ae000 r--p 00002000 00:01 1503       /lib/libdl-0.9.33.2.so
773ae000-773af000 rw-p 00003000 00:01 1503       /lib/libdl-0.9.33.2.so
773af000-773c5000 r-xp 00000000 00:01 1494       /lib/libpthread-0.9.33.2.so
773c5000-773d4000 ---p 00000000 00:00 0 
773d4000-773d5000 r--p 00015000 00:01 1494       /lib/libpthread-0.9.33.2.so
773d5000-773d6000 rw-p 00016000 00:01 1494       /lib/libpthread-0.9.33.2.so
773d6000-773d8000 rw-p 00000000 00:00 0 
773d8000-773e0000 r-xp 00000000 00:01 1495       /lib/ld-uClibc-0.9.33.2.so
773ee000-773ef000 rw-p 00000000 00:00 0 
773ef000-773f0000 r--p 00007000 00:01 1495       /lib/ld-uClibc-0.9.33.2.so
773f0000-773f1000 rw-p 00008000 00:01 1495       /lib/ld-uClibc-0.9.33.2.so
773f1000-773f2000 rw-p 00000000 00:00 0 
7fbf5000-7fc16000 rwxp 00000000 00:00 0          [stack]
7fff7000-7fff8000 r-xp 00000000 00:00 0          [vdso]
root@DESK /proc/601 [#]# 

上面的maps结果显示,增加的内存是创建线程时给线程的栈。当线程退出时,线程栈不是马上回收的,glibc允许缓存一部分内存块,只有当内存块的大小超过 stack_cache_maxsize 时才会释放掉一部分内存块

查看了uClibc的代码发现stack_cache_maxsize是40MB, 在嵌入式设备中,这个值太大了。

llwang@compiler~/repos/master_for_AA-12.09/osdk_repos/build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/uClibc-0.9.33.2 $ grep -rn 'stack_cache_maxsize' *
libpthread/nptl/allocatestack.c:103:static size_t stack_cache_maxsize = 40 * 1024 * 1024; /* 40MiBi by default.  */
libpthread/nptl/allocatestack.c:301:  if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0))
libpthread/nptl/allocatestack.c:302:    __free_stacks (stack_cache_maxsize);

修改

llwang@compiler~/repos/master_for_AA-12.09/osdk_repos $ cat  toolchain/uClibc/patches-0.9.33.2/961-pthread_stack_cache_size.patch
--- a/libpthread/nptl/allocatestack.c
+++ b/libpthread/nptl/allocatestack.c
@@ -100,7 +100,7 @@
 /* Cache handling for not-yet free stacks.  */
 
 /* Maximum size in kB of cache.  */
-static size_t stack_cache_maxsize = 40 * 1024 * 1024; /* 40MiBi by default.  */
+static size_t stack_cache_maxsize = 2 * 1024 * 1024; /* 2MiBi by default.  */
 static size_t stack_cache_actsize;
 
 /* Mutex protecting this variable.  */

参考

线程资源的分配和释放
glibc manual


nicephil@gmail.com – 2018-1-2

posted on 2018-01-02 14:39  nicephil  阅读(272)  评论(0编辑  收藏  举报

导航