valgrind 检测 php-fpm 内存泄漏

梦康 2016-12-09 00:00:00 690

最近线上服务器安装了一些扩展,导致 php-fpm 内存增长过快,虽然可以通过配置最大请求数和定时脚本来重启 php-fpm ,但是也抱着学习折腾的精神来学习下valgrind的使用。 下面的配置都是在我自己的服务器上测试,就是该博客运行的服务器上。

下载安装

wget http://valgrind.org/downloads/valgrind-3.12.0.tar.bz2
tar -jxvf valgrind-3.12.0.tar.bz2
cd valgrind-3.12.0
./autogen.sh
./configure
make
make intall

下载地址:http://valgrind.org/downloads/current.html#current

可能需要升级automakeautoconf

修改 php-fpm 启动命令

我我的脚本是/etc/init.d/php-fpm,需要做两个修改:在启动脚本中增加环境变量USE_ZEND_ALLOC=0以及将bin文件由原来的php-fpm文件修改为由valgrind启动,并将valgrind的日志重定向到日志文件中。

+ export USE_ZEND_ALLOC=0

- php_fpm_BIN=${exec_prefix}/sbin/php-fpm
+ php_fpm_BIN="valgrind --log-file=/data/log/valgrind-log-%p.log ${exec_prefix}/sbin/php-fpm"

重启 php-fpm

[root@VM_132_97_centos log]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
[root@VM_132_97_centos log]#  ps afx|grep php-fpm.pid
15694 pts/0    S+     0:00  |       \_ grep php-fpm.pid
15677 ?        Ss     0:00 valgrind --log-file=/data/log/valgrind-log-%p.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
15678 ?        S      0:00  \_ valgrind --log-file=/data/log/valgrind-log-%p.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
15679 ?        S      0:00  \_ valgrind --log-file=/data/log/valgrind-log-%p.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
15680 ?        S      0:00  \_ valgrind --log-file=/data/log/valgrind-log-%p.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
15681 ?        S      0:00  \_ valgrind --log-file=/data/log/valgrind-log-%p.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
15682 ?        S      0:00  \_ valgrind --log-file=/data/log/valgrind-log-%p.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
15683 ?        S      0:00  \_ valgrind --log-file=/data/log/valgrind-log-%p.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
[root@VM_132_97_centos log]# ll |grep valgrind
-rw-r--r-- 1 root root      1090 12月  9 10:34 valgrind-log-15634.log

查看日志

用上面的命令启动命令发现输出的数据非常有限

[root@VM_132_97_centos log]# cat valgrind-log-15634.log 
==15634== Memcheck, a memory error detector
==15634== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==15634== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==15634== Command: /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
==15634== Parent PID: 15633
==15634== 
==15634== 
==15634== HEAP SUMMARY:
==15634==     in use at exit: 677,491 bytes in 154 blocks
==15634==   total heap usage: 26,068 allocs, 25,914 frees, 3,325,059 bytes allocated
==15634== 
==15634== LEAK SUMMARY:
==15634==    definitely lost: 524,456 bytes in 7 blocks
==15634==    indirectly lost: 135,088 bytes in 12 blocks
==15634==      possibly lost: 360 bytes in 3 blocks
==15634==    still reachable: 17,587 bytes in 132 blocks
==15634==         suppressed: 0 bytes in 0 blocks
==15634== Rerun with --leak-check=full to see details of leaked memory
==15634== 
==15634== For counts of detected and suppressed errors, rerun with: -v
==15634== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

修改了启动命令,加上参数--leak-check=full

php_fpm_BIN="valgrind --leak-check=full --log-file=/data/log/valgrind-log-%p.log ${exec_prefix}/sbin/php-fpm"

这样日志就很具体了很多。

cat valgrind-log-20595.log 
==20595== Memcheck, a memory error detector
==20595== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==20595== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==20595== Command: /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid
==20595== Parent PID: 20594
==20595== 
==20595== 
==20595== HEAP SUMMARY:
==20595==     in use at exit: 677,491 bytes in 154 blocks
==20595==   total heap usage: 26,068 allocs, 25,914 frees, 3,325,059 bytes allocated
==20595== 
==20595== 32 bytes in 1 blocks are possibly lost in loss record 47 of 127
==20595==    at 0x4A0717A: malloc (vg_replace_malloc.c:298)
==20595==    by 0x7D83B8: __zend_malloc (zend_alloc.c:2866)
==20595==    by 0x8929C5: zend_string_alloc (zend_string.h:121)
==20595==    by 0x8929C5: zend_string_init (zend_string.h:157)
==20595==    by 0x8929C5: fcgi_set_mgmt_var (fastcgi.c:1724)
==20595==    by 0x893011: fcgi_init (fastcgi.c:487)
==20595==    by 0x89CD2A: main (fpm_main.c:1627)
==20595== 
==20595== 680 (24 direct, 656 indirect) bytes in 1 blocks are definitely lost in loss record 115 of 127
==20595==    at 0x4A0717A: malloc (vg_replace_malloc.c:298)
==20595==    by 0xC5755E9: ???
==20595==    by 0xC56144B: ???
==20595==    by 0xC552704: ???
==20595==    by 0x8027F2: zend_startup_module_ex (zend_API.c:1849)
==20595==    by 0x80A5C2: zend_hash_apply (zend_hash.c:1534)
==20595==    by 0x805319: zend_startup_modules (zend_API.c:1975)
==20595==    by 0x7A1264: php_module_startup (main.c:2217)
==20595==    by 0x89CB04: php_cgi_startup (fpm_main.c:837)
==20595==    by 0x89D37D: main (fpm_main.c:1812)

 

https://bugs.php.net/bugs-getting-valgrind-log.php

http://tina.reeze.cn/book/?p=chapt06/06-07-memory-leaks