Adrien Schuler
Adrien Schuler

Reputation: 2425

PHP Garbage Collector statistics

I'm doing some PHP memory benchmarks and i would like to obtain the garbage collector statics.

I've followed this tutorial in the official doc: http://www.php.net/manual/en/features.gc.performance-considerations.php

I've reproduced the exact procedure wich is described, by recompiling PHP with this CFLAGS environment variable :

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

I've done that with PHP 5.3.9 : http://fr.php.net/get/php-5.3.9.tar.bz2/from/a/mirror on a Debian Squeeze 6.0.4 64bits.

Then i tried to execute in command line the example script they provide 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";
?>

As they said, this should display at the end of the script, additional gc stats, for exemple :

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

The fact is, this gc statistics aren't displayed. It looks like that compiling PHP with this CFLAGS didn't made anything.

Did i missed something ?

Upvotes: 4

Views: 1195

Answers (1)

drew010
drew010

Reputation: 69937

I'm going on a hunch here as I've not confirmed this but, from reading the text on the GC link you provided, I don't get the impression that memory_get_peak_usage() should return additional information based on compiling PHP with the DGC_BENCH flag. The manual says it returns an int, so I suspect it always returns an int.

What it does say however is:

When you run the above example code again with the newly built PHP binary, you will see the following being shown after PHP has finished execution:

That isn't very clear, but I'm under the impression that the additional GC details will be printed to stdout or stderr rather than returned to memory_get_peak_usage() or being printed as additional output to your PHP script.

Try calling the newly built PHP executable from the command line and see if the GC information is printed to the console when the script finishes.

You can try calling it like: /path/to/custom/php testfile.php

I'm not sure it makes sense to output this information if you were running PHP as an Apache module or FastCGI handler so I suspect you may only be able to see it by calling your script from the console, but I could be totally wrong there.

UPDATE:

I've checked to make sure that the GC_BENCH compile flag is still active, and it is.

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

Next, I compiled PHP 5.3.9 for Apache2 and CLI. Before deciding to install the test version, I ran the new PHP CLI app from the console:

./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

It has the GC output even though I didn't invoke PHP. Next I grep'd libphp5.so and saw that it DOES have the GC Statistics bit compiled into it so I decided to install it live and make a call from Apache. No GC output in the browser, error_log, access_log, or any other log files.

Now the interesting part, I created a test.php file which outputs a string and creates a frees a few variables...

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# 

Conclusion:

When PHP is compiled with with GC_BENCH option, you will not have access to benchmark information when called from the browser, or when parsing PHP files by using the -f option or passing the name of the file to parse. You DO get benchmark information if you call php in interactive mode, or execute the script through PHP by reading it from stdin.

Upvotes: 3

Related Questions