PHPのVLDで無名関数を見るの記事の続きで、

<?php
$isEven = function($n){
        return ($n % 2 === 0);
};

if($isEven(2)){
        echo "even";
}else{
        echo "odd";
}

$isEven変数に割り当てた無名関数の処理を解除できるか?が気になった。

今回の内容に触れる前に割当の解除であるunsetについて触れておく。

PHP: unset - Manual




PHPで使用しているメモリの測定であるmemory_get_usage関数に良い例があったので、例を見ながらunsetを見ていく。


unset.php

<?php
//何も実行していない時のメモリ使用量を確認する
echo memory_get_usage() . "\n";

//2万字以上の長い文字列を用意する
$a = str_repeat("Hello", 4242);

//長い文字列の値を作成した後のメモリ使用量を確認する
echo memory_get_usage() . "\n";

//長い文字列の値を格納した変数の割当を解放する
unset($a);

//解放後のメモリ使用量を確認する
echo memory_get_usage() . "\n";

PHP: memory_get_usage - Manual


上記のコードの実行結果は下記の通り

$ php /path/to/dir/unset.php
397896
422504
397928

一行目は何もしていない時、二行目は長い文字列の処理の後で三行目は長い文字列の値をunset関数で解除した後のメモリの使用量になる。

unset後にメモリの使用量は大幅に低下した。

一行目と三行目に32バイトの差があるのは、変数自体で使用されるメモリなのだろう。


変数に割り当てられた値をunsetで解除しても、変数を定義した際のメモリの使用分は残るということは覚えておこう。

PHP: 変数入門 - Manual




今回の本題の変数に無名関数の処理を割り当てたものを解除できるのか?を試してみる。


unset_lambda.php

<?php
echo memory_get_usage() . "\n";

$isEven = function($n){
        return ($n % 2 === 0);
};

echo memory_get_usage() . "\n";

//一度は$isEvenの処理をしてみる
if($isEven(2)){
        echo "even\n";
}else{
        echo "odd\n";
}

unset($isEven);

echo memory_get_usage() . "\n";

上記のコードの実行結果は下記の通り

$ php /path/to/dir/unset_lambda.php
399056
399408
even
399088

unset.phpの結果同様、一行目と四行目の差が32バイトとなった。

$isEvenに割り当てられた無名関数の処理分は解除されたようだ。