PHPの /** から始まるコメントが、require_once実行時に無駄にメモリを食う問題

知り合いから教えてもらったのだが、PHPでは /** から始まるコメントが、require_once実行時に無駄にメモリを食う問題があるらしい・・・ということで調査してみた


まずは、確認用のコードとして test.php を書く

<?php
echo '         peek     usage'."\n";
echo 'pre    = '.memory_get_peak_usage().' / '.memory_get_usage()."\n";
$x  = '0123456789';
for ($i = 0; $i != 12; $i++) {
    $x = $x . $x; // 適当にメモリを使ってrequire_once 時に新たにメモリを確保する必要があるようにしておく
}
$before = memory_get_peak_usage();
echo 'before = '.$before.' / '.memory_get_usage()."\n";
require_once('hoge.php');
$after = memory_get_peak_usage();
echo 'after  = '.$after.' / '.memory_get_usage()."\n";
echo 'after - before = '.($after - $before)."\n\n";

echo 'strlen = '.strlen($x)."\n";


次に、require_onceするhoge.phpを書く

<?php
class hoge {
    /**
     * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
     * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
     * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
     * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
     * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
     */
    public function hogehoge0() {
        return '01234567890123456789012345678901234567890123456789';
    }
    public function hogehoge1() {
        return '01234567890123456789012345678901234567890123456789';
    }
    public function hogehoge2() {
        return '01234567890123456789012345678901234567890123456789';
    }
}

・・・で、test.phpを実行

[user@host ~]$ php  -v
PHP 5.3.10 (cli) (built: Mar 13 2012 10:54:48)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.1.4, Copyright (c) 2002-2012, by Derick Rethans

[user@host ~]$ php test.php
         peek     usage
pre    = 670656 / 639032
before = 703808 / 680448
after  = 706328 / 685792
after - before = 2520

strlen = 40960
strlen = 40960

require_once の前後で2520バイトピークのメモリ量が増えている


次に、コメントを /** から /* に変更して再度実行してみる

[user@host ~]$ php test.php
         peek     usage
pre    = 670656 / 639032
before = 703808 / 680448
after  = 705832 / 685296
after - before = 2024

strlen = 40960

require_once の前後で2024バイトピークのメモリ量が増えている

次は、 // コメントに変えてみる

[user@host ~]$ php test.php
         peek     usage
pre    = 670656 / 639032
before = 703808 / 680448
after  = 705832 / 685296
after - before = 2024

strlen = 40960

こちらも、require_once の前後で2024バイトピークのメモリ量が増えている


結果として /** 形式の場合、 /* や // の形式に比べて 496バイトほど無駄にメモリを使っている様子が見て取れ、たしかに/** から始まるコメントが、require_once実行時に無駄にメモリを食う問題が存在するようである。

ちなみに、/** の場合に、コメント自体の長さを増やすとどうなるのかさらに追試してみたところ、一文字増やすごとに増えるわけではないが、文字数が多ければ多いほど無駄にメモリを食っている様が見て取れた


・・・以上検証終わり


たぶん、require_once するときにプリプロセッサで // と /* のコメントは無視しているのに、なぜか /** は無視されないようになっている気がする
なお、requireや、include_once、includeでも起こるかどうかは未検証
・・・PHPのソースを負ったわけではないのであくまで「気がする」
・・・だれかバグか仕様かだけでも調査してくれる人いないかなー


追記(2012-08-16 22:25):
ブックマークに id:iakio さんよりコメントが有りました

下記の通り、PHPのリフレクションでドキュメントコメントを取得するものがあるそうで、 /** のコメントはその戻り値として用いられるため、この現象は仕様ということで良いようです。
http://jp.php.net/manual/ja/reflectionclass.getdoccomment.php

仕様ということですので、一応 タイトルの「問題」には取り消し線を入れておきます。