にゃあ

PHPのunset()とメモリの開放を調べてみた

メモリの使用量を調べるに当たって、検査用関数を作ってみた。初期メモリ使用量は無視して、純粋に変数で使われた容量を検出するもの。$initialMemoryUseですでに20バイトくらい使っている、というのは誤差の範囲で^^

function dumpMemory()
{
	static $initialMemoryUse = null;

	if ( $initialMemoryUse === null )
	{
		$initialMemoryUse = memory_get_usage();
	}

	var_dump(number_format(memory_get_usage() - $initialMemoryUse));
}

ケース1

dumpMemory(); // string(1) "0"

$hoge = array();

dumpMemory(); // string(3) "184"

for ( $i = 1; $i < 10000; $i++ )
{
	$hoge[$i] = null;
}

dumpMemory(); // string(7) "785,720"

for ( $i = 1; $i < 10000; $i++ )
{
	unset($hoge[$i]);
}

dumpMemory(); // string(6) "65,764"

んー、なんかものすごいオーバヘッドがあるんだけど。

ケース2

dumpMemory(); // string(1) "0"

$hoge = array();

dumpMemory(); // string(3) "184"

for ( $i = 1; $i < 10000; $i++ )
{
	$hoge[$i] = null;
	unset($hoge[$i]);
}

dumpMemory(); // string(3) "260"

ケース1の変形版。unsetのタイミングをforの中にしてみたら、かなりオーバヘッドが減った。理由はわかんない。

ケース3

dumpMemory(); // string(1) "0"

$hoge = array();

dumpMemory(); // string(3) "184"

for ( $i = 1; $i < 10000; $i++ )
{
	$hoge[$i] = null;
}

dumpMemory(); // string(7) "785,732"

unset($hoge);

dumpMemory(); // string(2) "96"

これもまたケース1の変形版。forでunset()しないで、配列まるごとunset()するようにしてみた。ケース2よりもオーバヘッドはひどくない。

ケース4

function scopeTest()
{
	$array = range(1, 10000);
	dumpMemory();
	// ここで$arrayはスコープを失う
}

dumpMemory(); // string(1) "0"

scopeTest(); // string(7) "785,700"

dumpMemory(); // string(2) "20"

今度はスコープでの実験。スコープが切れた変数はメモリから解放されると聞いていたけど、実際そのとおりみたい。

ケース5

class TestClass
{
	public static function test()
	{
		$array = range(1, 10000);
		dumpMemory();
		// ここでスコープを失う
	}
}

dumpMemory(); // string(1) "0"

TestClass::test(); // string(7) "785,680"

dumpMemory(); // string(2) "20"

ケース4をクラスにしてみただけ。静的関数でもスコープが切れた段階で、メモリが開放されていた。

結論みたいなもの

  • スコープ(寿命)が短い変数は特にunset()する必要はない。
  • グローバル(=寿命が長い)は変数は、うまいタイミングでunset()するか、できるだけスコープを短くしたほうがいい。
  • unset()の仕方によってはオーバヘッドがひどい。

ApacheからPHPを実行するくらいなら、プロセス自体の寿命も短いからメモリなんてそうそう気にならないけど、PHPでバッチ処理をしようとするとメモリ管理も大変になるんだよなあ。扱うデータ量が全然違ってくるし、プロセスの寿命も長いし。メモリを気にするならPHPなんてやめちまえ、ってこと?


コメント&トラバ

トラックバックを送る

無関係なスパムのトラックバックを防止するため、リンク先で本サイト(suin.asia)への言及が確認されないトラックバックは破棄しています。

トラバURL : http://suin.asia/trackback/507

コメントを書く

お名前* URL
本文*
合い言葉* ←「erperitics」と入力して下さい。
* この記事の話題と関係ないコメントはどんな内容でも削除します。(移動できないので)

トラックバック

トラックバックがないのはさみしいにゃん…。

コメント

あるある(2011.06.11) #
貴重な実験結果の公表、ありがとうございます。

Author

Submenu

Recent Entries

XOOPS Cube Dev Ring

氷川 XOOPS Module 開発室

Recent Comments

Recent Trackbacks