PHP垃圾收集器统计信息


PHP Garbage Collector statistics

我正在做一些PHP内存基准测试,我想获得垃圾收集器静态信息。

我在官方文档中遵循了此教程:http://www.php.net/manual/en/features.gc.performance-considerations.php

通过使用以下CFLAGS环境变量重新编译PHP,我复制了所描述的确切过程:

export CFLAGS=-DGC_BENCH=1
./config.nice
make clean
make
make install

我已经用PHP 5.3.9做到了这一点:http://fr.php.net/get/php-5.3.9.tar.bz2/from/a/mirror在Debian挤压6.0.4 64位上。

然后我尝试在命令行中执行他们提供的示例脚本php gc.php:

<?php
class Foo
{
    public $var = '3.1415962654';
}
for ( $i = 0; $i <= 1000000; $i++ )
{
    $a = new Foo;
    $a->self = $a;
}
echo memory_get_peak_usage(), "'n";
?>

正如他们所说,这个应该显示在脚本的末尾,附加的gc统计信息,例如:

GC Statistics
-------------
Runs:               110
Collected:          2072204
Root buffer length: 0
Root buffer peak:   10000
      Possible            Remove from  Marked
        Root    Buffered     buffer     grey
      --------  --------  -----------  ------
ZVAL   7175487   1491291    1241690   3611871
ZOBJ  28506264   1527980     677581   1025731

事实是,这个gc统计信息并没有显示出来。看起来用这个CFLAGS编译PHP并没有产生任何效果。

我错过什么了吗?

我有预感,因为我还没有证实这一点,但从阅读您提供的GC链接上的文本来看,我不认为memory_get_peak_usage()应该返回基于使用DGC_BENCH标志编译PHP的附加信息。手册上说它返回int,所以我怀疑它总是返回int

然而,它所做的所说的是:

当您使用新构建的PHP再次运行上面的示例代码时二进制文件,您将在PHP完成后看到以下内容执行:

这还不太清楚,但我的印象是,额外的GC详细信息将打印到stdoutstderr,而不是返回到memory_get_peak_usage()或作为PHP脚本的额外输出打印。

尝试从命令行调用新构建的PHP可执行文件,并查看脚本完成时GC信息是否打印到控制台。

你可以试着这样称呼它:/path/to/custom/php testfile.php

如果你将PHP作为Apache模块或FastCGI处理程序运行,我不确定输出这些信息是否有意义,所以我怀疑你可能只能通过从控制台调用脚本来看到它,但我可能完全错了。

更新:

我已经检查以确保GC_BENCH编译标志仍然处于活动状态,并且是.

Zend/Zend.c


905 #if GC_BENCH
906     fprintf(stderr, "GC Statistics'n");
907     fprintf(stderr, "-------------'n");
908     fprintf(stderr, "Runs:               %d'n", GC_G(gc_runs));
909     fprintf(stderr, "Collected:          %d'n", GC_G(collected));
910     fprintf(stderr, "Root buffer length: %d'n", GC_G(root_buf_length));
911     fprintf(stderr, "Root buffer peak:   %d'n'n", GC_G(root_buf_peak));
912     fprintf(stderr, "      Possible            Remove from  Marked'n");
913     fprintf(stderr, "        Root    Buffered     buffer     grey'n");
914     fprintf(stderr, "      --------  --------  -----------  ------'n");
915     fprintf(stderr, "ZVAL  %8d  %8d  %9d  %8d'n", GC_G(zval_possible_root), GC_G(zval_buffered), GC_G(zval_remove_from_buffer), GC_G(zval_marked_grey));
916     fprintf(stderr, "ZOBJ  %8d  %8d  %9d  %8d'n", GC_G(zobj_possible_root), GC_G(zobj_buffered), GC_G(zobj_remove_from_buffer), GC_G(zobj_marked_grey));
917 #endif

接下来,我为Apache2和CLI编译了PHP 5.3.9。在决定安装测试版本之前,我从控制台运行了新的PHP CLI应用程序:

./sapi/cli/php -v
PHP 5.3.9 (cli) (built: Feb 22 2012 19:03:02) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
GC Statistics
-------------
Runs:               0
Collected:          0
Root buffer length: 0
Root buffer peak:   7
      Possible            Remove from  Marked
        Root    Buffered     buffer     grey
      --------  --------  -----------  ------
ZVAL        15         7          7         0
ZOBJ         0         0          0         0

即使我没有调用PHP,它也有GC输出。接下来,我对libphp5.so进行了grep,发现它确实编译了GC统计信息,所以我决定实时安装它,并从Apache进行调用。浏览器、error_log、access_log或任何其他日志文件中没有GC输出。

现在有趣的部分,我创建了一个test.php文件,该文件输出一个字符串并创建一个释放一些变量。。。

root@vm:/php539# php test.php
This is a test
root@vm:/php539# php < test.php
This is a test
GC Statistics
-------------
Runs:               0
Collected:          0
Root buffer length: 0
Root buffer peak:   7
      Possible            Remove from  Marked
        Root    Buffered     buffer     grey
      --------  --------  -----------  ------
ZVAL        16         7          7         0
ZOBJ         0         0          0         0
root@vm:php539# 

结论:

当使用GC_BENCH选项编译PHP时,在从浏览器调用时,或者在使用-f选项解析PHP文件或传递要解析的文件名时,您将无法访问基准信息。如果您在交互模式下调用php,或者通过从stdin读取php来执行脚本,那么您确实可以获得基准测试信息。