![Apache strace 查找内存泄漏](https://linux22.com/image/602381/Apache%20strace%20%E6%9F%A5%E6%89%BE%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F.png)
我们的服务器存在内存问题:服务器不断为自己分配内存,并且不释放它。我们正在运行 Apache。我将 MaxReqsPerClient 设置为非常低的值,这样线程就不会占用太多内存,但有人见过这样的调用吗?我认为可能是 Drupal 从 DB 中的缓存中拉回了太多数据,我错了吗?
read(52, "h_index\";a:2:{s:6:\"weight\";i:1;s"..., 6171) = 1368
read(52, "\";a:2:{s:6:\"author\";a:3:{s:5:\"la"..., 4803) = 1368
read(52, ":\"description\";s:19:\"Term name t"..., 3435) = 1368
read(52, "abel\";s:4:\"Name\";s:11:\"descripti"..., 2067) = 1368
read(52, "ions\";a:2:{s:4:\"form\";a:3:{s:4:\""..., 16384) = 708
brk(0x2ab554396000) = 0x2ab5542f5000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ab55f653000
brk(0x2ab554356000) = 0x2ab5542f5000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ab55f753000
brk(0x2ab554356000) = 0x2ab5542f5000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ab55f853000
brk(0x2ab554356000) = 0x2ab5542f5000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ab55f953000
brk(0x2ab554356000) = 0x2ab5542f5000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ab55fa53000
brk(0x2ab554356000) = 0x2ab5542f5000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ab55fb53000
brk(0x2ab554356000) = 0x2ab5542f5000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ab55fc53000
poll([{fd=52, events=POLLIN|POLLPRI}], 1, 0) = 0 (Timeout)
write(52, "d\0\0\0\3SELECT cid, data, created, "..., 104) = 104
read(52, "\1\0\0\1\5E\0\0\2\3def\23drupal_database_nam"..., 16384) = 1368
read(52, ";s:11:\"granularity\";a:5:{s:4:\"ye"..., 34783) = 1368
read(52, ":4:\"date\";}s:9:\"datestamp\";a:9:{"..., 33415) = 1368
read(52, "\";i:0;s:15:\"display_default\";i:0"..., 32047) = 1368
read(52, "e as an integer value.\";s:8:\"set"..., 30679) = 1368
read(52, "label' pairs, i.e. 'Fraction': 0"..., 29311) = 1368
顶部(进程在内存中不断增长..):
12845 apache 15 0 581m 246m 37m S 0.0 4.1 0:17.39 httpd
12846 apache 15 0 571m 235m 37m S 0.0 4.0 0:12.13 httpd
12833 apache 15 0 420m 117m 37m S 0.0 2.0 0:06.04 httpd
12851 apache 15 0 412m 113m 37m S 0.0 1.9 0:05.32 httpd
13871 apache 15 0 409m 109m 37m S 0.0 1.8 0:04.90 httpd
12844 apache 15 0 407m 108m 37m S 0.0 1.8 0:04.50 httpd
13870 apache 15 0 407m 108m 37m S 0.3 1.8 0:03.50 httpd
14903 apache 15 0 402m 103m 37m S 0.3 1.7 0:01.29 httpd
14850 apache 15 0 397m 100m 37m S 0.0 1.7 0:02.08 httpd
14907 apache 15 0 390m 93m 36m S 0.0 1.6 0:01.32 httpd
13872 apache 15 0 386m 91m 37m S 0.0 1.5 0:03.13 httpd
12843 apache 15 0 373m 81m 37m S 0.0 1.4 0:02.51 httpd
14901 apache 15 0 370m 75m 33m S 0.0 1.3 0:00.78 httpd
14904 apache 15 0 335m 29m 15m S 0.0 0.5 0:00.26 httpd
答案1
这是在什么时间段发生的?内存使用量有多大?
如果时间足够短,或者你暂时不在前台运行 Apache,则可以使用瓦尔格林德查找内存泄漏...(可通过 YUM 获得)
就像是:
valgrind --leak-check=full /usr/sbin/httpd
输出可能会显示类似以下内容:
==945== LEAK SUMMARY:
==945== definitely lost: 15,595 bytes in 120 blocks
==945== indirectly lost: 1,917,248 bytes in 1,242 blocks
==945== possibly lost: 0 bytes in 0 blocks
==945== still reachable: 11,743 bytes in 89 blocks
==945== suppressed: 0 bytes in 0 blocks
==945== Reachable blocks (those to which a pointer was found) are not shown.
==945== To see them, rerun with: --leak-check=full --show-reachable=yes
对于 Apache,我会查看 PID。使用以下命令获取 PID 值:cat /var/run/httpd.pid
或者直接运行:
pmap -x $(cat /var/run/httpd.pid)
但以我有限的 Apache 经验来看,泄漏似乎总是与模块和脚本语言有关。也可能是缓存...
答案2
我最终只是降低了 httpd.conf 中的 MaxRequestsPerChild,这样我的线程在变得太大之前就会过期。它们之前会达到 800M,并且进行了一些严重的交换,现在它们最多会达到 250M 就会过期。