xhprof php7问题

xhprof php7问题

xhprof 是facebook 开发的一个测试php性能的扩展,

现存的问题

xhprof不支持php7,代码已经几年没有更新过了, 由于Facebook的优化方向是HHVM,所以这个扩展可以预见不会再有官方维护了。

目前github上有一些个人维护的php7版本, 但是完成的质量都不高,存在各种坑,很不幸我们踩了一个: 内存泄漏

内存泄漏

test环境之前安装的版本:
https://github.com/RustJason/xhprof/tree/php7

之前用着一直好好的, 一经压测就完蛋了,原因就是内存泄漏。

用valgrind检测结果, 摘抄部分如下:

==19323== 32 bytes in 1 blocks are definitely lost in loss record 10 of 30
==19323==    at 0x4C2210C: malloc (vg_replace_malloc.c:195)
==19323==    by 0x7F76AA: __zend_malloc (zend_alloc.c:2853)
==19323==    by 0xA5B9534: zend_string_alloc (zend_string.h:121)
==19323==    by 0xA5B94DB: zend_string_init (zend_string.h:157)
==19323==    by 0xA5B9E3F: hp_begin (xhprof.c:1688)
==19323==    by 0xA5B7D4D: zif_xhprof_enable (xhprof.c:403)
==19323==    by 0xA5B9B68: hp_execute_internal (xhprof.c:1586)
==19323==    by 0x883CFC: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==19323==    by 0x882A30: execute_ex (zend_vm_execute.h:417)
==19323==    by 0xA5B980C: hp_execute_ex (xhprof.c:1527)
==19323==    by 0x882B47: zend_execute (zend_vm_execute.h:458)
==19323==    by 0x82A134: zend_execute_scripts (zend.c:1427)

...................等等...................


==19323== LEAK SUMMARY:
==19323==    definitely lost: 192 bytes in 6 blocks
==19323==    indirectly lost: 0 bytes in 0 blocks
==19323==      possibly lost: 0 bytes in 0 blocks
==19323==    still reachable: 2,633 bytes in 26 blocks
==19323==         suppressed: 0 bytes in 0 blocks
==19323== Reachable blocks (those to which a pointer was found) are not shown.
==19323== To see them, rerun with: --leak-check=full --show-reachable=yes

可以看到明显有内存泄漏: definitely lost: 192 bytes in 6 blocks
从上面的日志可以看出问题所在的调用栈:

xhprof_enable() -> hp_begin() -> zend_string_init() -> zend_string_alloc() -> __zend_malloc() -> malloc()

对着扩展的源码找一下问题出在哪:

static void hp_begin(long level, long xhprof_flags TSRMLS_DC) {
    ................something.....................
    BEGIN_PROFILING(&hp_globals.entries, zend_string_init(ROOT_SYMBOL, sizeof(ROOT_SYMBOL) - 1, 1), hp_profile_flag);
    return;

    ..............................

这块申请了内存, 但是并没有进行释放!看了下代码这个问题有些复杂, 下面这个结构体是一个全局变量保存了所有php函数的调用栈, 以及每个函数用的时间、cpu使用等信息。zend_string 是用来保存函数名的,就是这一块的内存发生了泄漏。由于这是一个全局变量, 整体代码中这个结构体耦合非常高, 改起来不容易。

typedef struct hp_entry_t {
  zend_string             *name_hprof;                       /* function name */
  int                     rlvl_hprof;        /* recursion level for function */
  uint64                  tsc_start;         /* start value for TSC counter  */
  long int                mu_start_hprof;                    /* memory usage */
  long int                pmu_start_hprof;              /* peak memory usage */
  struct rusage           ru_start_hprof;             /* user/sys time start */
  struct hp_entry_t      *prev_hprof;    /* ptr to prev entry being profiled */
  uint8                   hash_code;     /* hash_code for the function name  */

而且,这个版本完成的质量不高,其作者也在readme中提到”
Please do not use this in an production env.生产环境勿用。代码简直没法看。

所以我放弃直接修复这个版本的bug, 而选择寻找其他方案

解决办法

在尝试解决问题的时候发现了一个扩展Tideways, 这是基于xhprof的二次开发版本,是一整套解决方案(包括xhprof,以及性能分析的图形化界面等等)。需要注意的是这是一个这是一个商业版本, 其中图形化性能分析工具是收费的, xhprof功能是免费的, 对我们来说已经够用了。

测试了一下:

  1. 用法与xhprof一样,功能没有问题,满足我们需求
  2. valgrind检测无内存泄漏
  3. 压测内存未见异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值