メモリの使用量を調べるに当たって、検査用関数を作ってみた。初期メモリ使用量は無視して、純粋に変数で使われた容量を検出するもの。$initialMemoryUseですでに20バイトくらい使っている、というのは誤差の範囲で^^
function dumpMemory()
{
static $initialMemoryUse = null;
if ( $initialMemoryUse === null )
{
$initialMemoryUse = memory_get_usage();
}
var_dump(number_format(memory_get_usage() - $initialMemoryUse));
}
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"
んー、なんかものすごいオーバヘッドがあるんだけど。
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の中にしてみたら、かなりオーバヘッドが減った。理由はわかんない。
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よりもオーバヘッドはひどくない。
function scopeTest()
{
$array = range(1, 10000);
dumpMemory();
// ここで$arrayはスコープを失う
}
dumpMemory(); // string(1) "0"
scopeTest(); // string(7) "785,700"
dumpMemory(); // string(2) "20"
今度はスコープでの実験。スコープが切れた変数はメモリから解放されると聞いていたけど、実際そのとおりみたい。
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をクラスにしてみただけ。静的関数でもスコープが切れた段階で、メモリが開放されていた。
ApacheからPHPを実行するくらいなら、プロセス自体の寿命も短いからメモリなんてそうそう気にならないけど、PHPでバッチ処理をしようとするとメモリ管理も大変になるんだよなあ。扱うデータ量が全然違ってくるし、プロセスの寿命も長いし。メモリを気にするならPHPなんてやめちまえ、ってこと?
トラバURL : http://suin.asia/trackback/507
氷川 XOOPS Module 開発室