PHP 5.3 でガーベジコレクションは新しくなったのか
ガベージコレクタ が追加され、デフォルトで有効になりました。
PHP: 新機能 - Manual
で、前々から噂されている通り、循環参照をうまく処理できるようになった、のか?
ということでちょっと検証してみました。
環境
どちらも、iMac上のVMWare Server 上のUbuntu(バージョんは違うけど)。メモリは512MB割り当ててる。
PHP 5.2.9
% php -v PHP 5.2.9-0.dotdeb.2 with Suhosin-Patch 0.9.7 (cli) (built: Apr 7 2009 20:42:41) Copyright (c) 1997-2009 The PHP Group % cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=8.10 DISTRIB_CODENAME=intrepid DISTRIB_DESCRIPTION="Ubuntu 8.10"
PHP 5.3
% php -v PHP 5.3.0-0.dotdeb.6 (cli) (built: Jul 3 2009 09:22:56) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies % cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=9.04 DISTRIB_CODENAME=jaunty DISTRIB_DESCRIPTION="Ubuntu 9.04"
検証用スクリプト
循環参照ナシ
% cat gc_no_circle.php <?php ini_set("memory_limit", -1); class Piyo { public $hoge; function __construct() { $this->hoge = new Hoge(); } } class Hoge { function __construct() { $this->Fuga = new Fuga(); } } class Fuga { function __construct() { } } $test = 100000; printf("test\n%20s MB \n", round(memory_get_usage()/1024/1024, 10)); foreach (range(0, $test) as $i) { $piyo = new Piyo(); unset($piyo); if ($i % ($test/10) === 0) { printf("%10d: %15s MB \n", $i, round(memory_get_usage()/1024/1024, 10)); } } printf("max\n%20s MB \n", round(memory_get_peak_usage()/1024/1024, 10));
循環参照アリ
% cat gc_circle.php <?php /** * * */ ini_set("memory_limit", -1); class Piyo { public $hoge; public $fuga; function __construct() { $this->hoge = new Hoge($this); $this->fuga = new Fuga($this); } } class Hoge { public $piyo; function __construct(&$piyo) { $this->piyo = $piyo; } } class Fuga { public $piyo; function __construct(&$piyo) { $this->piyo = $piyo; } } $test = 100000; printf("test\n%20s MB \n", round(memory_get_usage()/1024/1024, 10)); foreach (range(0, $test) as $i) { $piyo = new Piyo(); unset($piyo); if ($i % ($test/10) === 0) { printf("%10d: %15s MB \n", $i, round(memory_get_usage()/1024/1024, 10)); } } printf("max\n%20s MB \n", round(memory_get_peak_usage()/1024/1024, 10));
結果
PHP 5.2.9
% php gc_no_circle.php test 0.0661392212 MB 0: 10.104927063 MB 10000: 10.10496521 MB 20000: 10.10496521 MB 30000: 10.10496521 MB 40000: 10.10496521 MB 50000: 10.10496521 MB 60000: 10.10496521 MB 70000: 10.10496521 MB 80000: 10.10496521 MB 90000: 10.10496521 MB 100000: 10.10496521 MB max 10.10521698 MB % php gc_circle.php test 0.0684661865 MB 0: 10.1074295044 MB 10000: 19.2648048401 MB 20000: 28.4455986023 MB 30000: 38.3764038086 MB 40000: 46.8072090149 MB 50000: 58.2380065918 MB 60000: 66.6688117981 MB 70000: 75.0996170044 MB 80000: 83.5304222107 MB 90000: 97.9612159729 MB 100000: 106.392021179 MB max 106.392383575 MB
PHP 5.3
% php gc_no_circle.php test 0.6073989868 MB 0: 14.5778503418 MB 10000: 14.5778503418 MB 20000: 14.5778503418 MB 30000: 14.5778503418 MB 40000: 14.5778503418 MB 50000: 14.5778503418 MB 60000: 14.5778503418 MB 70000: 14.5778503418 MB 80000: 14.5778503418 MB 90000: 14.5778503418 MB 100000: 14.5778503418 MB max 14.5806121826 MB % php gc_circle.php test 0.610710144 MB 0: 14.5822753906 MB 10000: 15.522064209 MB 20000: 15.5232086182 MB 30000: 15.5243530273 MB 40000: 15.5254974365 MB 50000: 15.5266418457 MB 60000: 15.5277862549 MB 70000: 15.5289306641 MB 80000: 15.5300750732 MB 90000: 15.5312194824 MB 100000: 15.5323638916 MB max 19.3443527222 MB
速度とか
PHP 5.2.9
% for ((i = 0; i < 5; i += 1)) ; do time php gc_no_circle.php >/dev/null ; done; php gc_no_circle.php > /dev/null 0.28s user 0.06s system 100% cpu 0.337 total php gc_no_circle.php > /dev/null 0.31s user 0.02s system 99% cpu 0.331 total php gc_no_circle.php > /dev/null 0.31s user 0.01s system 98% cpu 0.324 total php gc_no_circle.php > /dev/null 0.28s user 0.04s system 98% cpu 0.326 total php gc_no_circle.php > /dev/null 0.29s user 0.04s system 100% cpu 0.328 total % for ((i = 0; i < 5; i += 1)) ; do time php gc_circle.php >/dev/null ; done; php gc_circle.php > /dev/null 0.59s user 0.26s system 99% cpu 0.850 total php gc_circle.php > /dev/null 0.60s user 0.28s system 93% cpu 0.942 total php gc_circle.php > /dev/null 0.58s user 0.28s system 99% cpu 0.860 total php gc_circle.php > /dev/null 0.59s user 0.25s system 99% cpu 0.841 total php gc_circle.php > /dev/null 0.60s user 0.25s system 100% cpu 0.843 total
PHP 5.3
% for ((i = 0; i < 5; i += 1)) ; do time php gc_no_circle.php >/dev/null ; done; php gc_no_circle.php > /dev/null 0.20s user 0.04s system 97% cpu 0.245 total php gc_no_circle.php > /dev/null 0.20s user 0.05s system 100% cpu 0.249 total php gc_no_circle.php > /dev/null 0.19s user 0.06s system 104% cpu 0.240 total php gc_no_circle.php > /dev/null 0.20s user 0.05s system 99% cpu 0.251 total php gc_no_circle.php > /dev/null 0.22s user 0.02s system 100% cpu 0.240 total % for ((i = 0; i < 5; i += 1)) ; do time php gc_circle.php >/dev/null ; done; php gc_circle.php > /dev/null 0.93s user 0.03s system 100% cpu 0.956 total php gc_circle.php > /dev/null 0.90s user 0.04s system 99% cpu 0.940 total php gc_circle.php > /dev/null 0.90s user 0.05s system 99% cpu 0.956 total php gc_circle.php > /dev/null 0.93s user 0.03s system 99% cpu 0.965 total php gc_circle.php > /dev/null 0.91s user 0.05s system 99% cpu 0.967 total