PHPのメモリ管理について(値渡し)

このエントリーをはてなブックマークに追加

notoです。

PHPのメモリ管理はどういう仕組みで動いているのか少し調べてみたので、その検証です。

 

PHPの変数管理については、「はじめに-PHP変数管理解説(1)-参照と値渡しの明確な理解のために」がわかりやすくまとまっていると思うので、初めに目を通したほうがいいと思います。

 

zvalの確認方法

zvalの中身を確認するには、debug_zval_dump関数とxdebug_debug_zval関数があります。
xdebug_debug_zval関数はリファレンスカウンタも表示してくれますので、こちらを利用します。

※xdebug_debug_zval関数を利用するには、xdebugをインストールする必要があります。

 

値渡しと参照渡し

値渡しと参照渡しはどう管理されているのか確認していきます。

値渡しサンプル

<?php
$hoge = 'ほげ';

$piyo = $hoge;

xdebug_debug_zval('hoge');
xdebug_debug_zval('piyo');

 
この実行結果はどうなるでしょうか。
 
シンボルテーブル

変数名 zval No
hoge #0001
piyo #0002

 
zval

No Value refcount is_ref
#0001 ほげ 1 0
#0002 ほげ 1 0

 
こうだと思った方はもう一度、はじめに-PHP変数管理解説(1)-参照と値渡しの明確な理解のためにを読みなおしてください。

 
実行結果

hoge: (refcount=2, is_ref=0)='ほげ'
piyo: (refcount=2, is_ref=0)='ほげ'

 
シンボルテーブル

変数名 zval No
hoge #0001
piyo #0001

 
zval

No Value refcount is_ref
#0001 ほげ 2 0

 
この時、refcount=2となっています。refcountは、zvalコンテナがシンボルテーブルといくつリンクしているかを表しています。

これだと参照渡しに見えますよね。では、変数 piyoに値を代入してみます。
 

<?php
$hoge = 'ほげ';

$piyo = $hoge;

xdebug_debug_zval('hoge');
xdebug_debug_zval('piyo');

echo 'piyoに値を代入', PHP_EOL;

$piyo = 'ぴよ';

xdebug_debug_zval('hoge');
xdebug_debug_zval('piyo');


 

実行結果

hoge: (refcount=2, is_ref=0)='ほげ'
piyo: (refcount=2, is_ref=0)='ほげ'
piyoに値を代入
hoge: (refcount=1, is_ref=0)='ほげ'
piyo: (refcount=1, is_ref=0)='ぴよ'

 
シンボルテーブル

変数名 zval No
hoge #0001
piyo #0002

 
zval

No Value refcount is_ref
#0001 ほげ 1 0
#0002 ぴよ 1 0

 

変数 piyoに値を代入する前は同じzvalコンテナとリンクしていましたが、代入された後は新たに「ぴよ」という値が書き込まれたのが確認できます。

PHPの値渡しはこういう仕組みで動いていたんですね。そもそもシンボルテーブルの存在すら知りませんでした。。。

少し長くなってしまったので次回に参照渡しの検証について書きます。

    • さかい
    • 2012 01/15 12:31pm

    おーこれは確かに重要ですね。
    値コピーで無意識に参照カウントしてるとかしらんかったー。

    ちなみにPerlではリファレンスという機能があって意図的に参照カウントを操作できるので
    頭悩ますことは無いのですよー。Perlかわいくなってきたよ。

      • noto
      • 2012 01/15 5:42pm

      phpもperlもガベージコレクションには、リファレンスカウント方式を使用してるから、循環参照は気をつけなくてはいけないね。

      perfect vimmerになってきたか(笑)

return top