PHP Performance Ultimate Debug-Generate Flame Graph


I just started to learn PHP in 2012. At that time, the PHP application was very simple. There were not too many complicated design patterns, such as dependency injection and factory patterns. The Reflection API was just coming out at that time. A PHP application was just a package of front-ends. The script file of the code, because of the simplicity and reliability of PHP, and the extremely low cost of learning, PHP became a smash hit in those few years. You can quickly understand the PHP code written by others, no matter how bad it is. At that time, I just graduated with a proficiency in PHP and could easily get a salary of 7,000 or 8,000 in the third and fourth tier cities. In addition, the source code research of the major frameworks (Tp, Ci, Yii, Cphalcon) at that time was very thorough, and I thought I had already touched it. To the ceiling of PHP. Later, I changed the city to write PHP a lot less, and I used a set of frameworks based on Swoole, which is handy.

However, the company where I work now, PHP occupies 90% of the share, basically Laravel/Lumen applications, which makes it difficult for me to continue to do performance optimization. Laravel uses a large number of design patterns and dynamic injections. In many cases, the specific object instance can only be known at runtime. It is difficult to determine the running status of the service only by looking at the source code. Therefore, flame graphs and visual call stacks are very important when doing performance analysis, and can be very intuitive and accurate to see all kinds of time-consuming.

In PHP, we can focus on two levels of flame graphs: PHP kernel and PHP Zend call stack . The former is the time-consuming flame graph of grabbing system calls, and the latter is the time-consuming flame graph of Zend VM. The following two types of flame graph generation are shared.

囧, SVG format pictures cannot be uploaded, students who want to see pictures enter my blog, the link is at the bottom.

Operating environment

Operating System (Arch Linux)

# neofech
                   -`                    russell@T14 
                  .o+`                   ----------- 
                 `ooo/                   OS: Arch Linux x86_64 
                `+oooo:                  Host: NBLK-WAX9X M1040 
               `+oooooo:                 Kernel: 5.14.14-arch1-1 
               -+oooooo+:                Uptime: 1 hour, 15 mins 
             `/:-:++oooo+:               Packages: 852 (pacman) 
            `/++++/+++++++:              Shell: zsh 5.8 
           `/++++++++++++++:             Resolution: 1920x1080 
          `/+++ooooooooooooo/`           DE: Plasma 5.23.2 
         ./ooosssso++osssssso+`          WM: KWin 
        .oossssso-````/ossssss+`         WM Theme: Breeze 
       -osssssso.      :ssssssso.        Theme: Breeze Light [Plasma], Breeze [GTK2/3] 
      :osssssss/        osssso+++.       Icons: Uos-fulldistro-icons [Plasma], Uos-fulldi 
     /ossssssss/        +ssssooo/-       Terminal: konsole 
   `/ossssso+/:-        -:/+osssso+-     Terminal Font: Hack 10 
  `+sso+:-`                 `.-/+oso:    CPU: AMD Ryzen 5 3500U with Radeon Vega Mobile G 
 `++:.                           `-/+/   GPU: AMD ATI 03:00.0 Picasso 
 .`                                 `/   Memory: 1928MiB / 6880MiB

PHP version

# php -v
PHP 7.4.23 (cli) (built: Sep 19 2021 12:07:04) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v3.1.1, Copyright (c) 2002-2021, by Derick Rethans

There is no requirement for this, version 5.6 and above.

Laravel version

# php artisan -V
Laravel Framework 8.61.0

perf version

# perf -v
perf version 5.14.g7d2a07b76933

Download flamegraph

git clone
cd FlameGraph
# 这一步是将 FlameGraph 注入到可执行文件系统路径中,下面就可以直接执行里面的工具了
export PATH=`pwd`:$PATH

This tool is the key. It takes time to capture system calls through perf and then generate flame graphs.

Grab the PHP kernel flame map

First find the PHP process ID, and then use the following command to grab

# 抓取 PID 为 7959 进程 60 秒
perf record -F 99 -p 7959 -g -- sleep 30

Export stack

perf script > out.perf

Generate Fold stacks file out.perf > out.folded

Generate flame graph out.folded > php-zend-flame-graph.svg

Take a look at the effect, svg format picture, you can click the flame bar to filter (open a new tab to view):

Grab the time-consuming flame graph of Zend VM

The flame graph generation relies on xdebug, and different xdebug versions use different configurations. For configuration instructions, you can directly see the package configuration file or go to 16186c9b38862f Github .

Xdebug3 configuration:

xdebug.trace_output_name = xdebug.trace.%t.%s
xdebug.output_dir = /tmp

Xdebug2 configuration:

xdebug.trace_output_name = xdebug.trace.%t.%s
xdebug.trace_enable_trigger = 1
xdebug.trace_output_dir = /tmp
xdebug.trace_enable_trigger_value = "<secret key>"

Request the interface url to get the php stack data curl<secret key> . The trace file is in the /tmp directory and starts with xdebug.tarce.

Convert the stack data (if stackcollapse-xdebug.php does not exist, pay attention to the download flamegraph above):

stackcollapse-xdebug.php /tmp/xdebug.trace.1635786267._data_workspaces_study_laravel-framework_laravel_server_php.xt

gz trace file is in 06186c9b3886c7 format, convert it:

# 参数 `-dk` 表示解压并保留源文件。
gzip -dk /tmp/xdebug.trace.1635786267._data_workspaces_study_laravel-framework_laravel_server_php.xt.gz

Convert stack data

stackcollapse-xdebug.php xdebug.trace.1635786267._data_workspaces_study_laravel-framework_laravel_server_php.xt > out.folded

Generate flame graph out.folded > laravel-flame-graph.svg

Take a look at the effect, svg format picture, you can click the flame bar to filter (open a new tab to view):

The article was first published on my blog:

阅读 1.9k



643 声望
13 粉丝
0 条评论


643 声望
13 粉丝