現在の言語: 日本語 |
cow(copy on write) |
メモリ解放関連 |
class test1
{
function test1()
{
//$aに文字列を設定した時点で1つのデータが存在します(参照カウント:1)
$a = "init";
echo "(1)メモリ使用量: " . memory_get_usage() . " バイト\n";//(1)メモリ使用量: (例)429472 バイト
//この時点で$aと$bが同じメモリ領域を参照します(参照カウント:2)
$b = $a;
echo "(2)メモリ使用量: " . memory_get_usage() . " バイト\n";//(2)メモリ使用量: (例)429472 バイト
//$aおよび$bおよび$cは同じメモリを参照します(参照カウント:3)
$c = $a;
echo "(3)メモリ使用量: " . memory_get_usage() . " バイト\n";//(3)メモリ使用量: (例)429472 バイト
//この時点で$b用に新しいメモリ領域が確保され、データがコピーされます
//$aと$cは元のメモリ領域を参照したままとなります
$b .= " add";
echo "(4)メモリ使用量: " . memory_get_usage() . " バイト\n";//(4)メモリ使用量: (例)429512 バイト
}
function test2()
{
//[COWによるメモリ解放]
echo "スクリプト開始時のメモリ使用量: " . memory_get_usage() . " バイト\n";
// 1. 大きな文字列を作成
$a = str_repeat('a', 1024 * 1024); // 1MBの文字列
echo "\$a 作成後のメモリ使用量: " . memory_get_usage() . " バイト\n";
// ここで約1MBメモリが増える
// 2. COWによる代入(メモリ共有)
$b = $a;
// この時点では新しいメモリは確保されない(参照カウントが増えるだけ)
echo "\$b = \$a 実行後のメモリ使用量: " . memory_get_usage() . " バイト\n";
// メモリ使用量はほぼ変わらない
// 3. COWの解除(書き込み発生)
// $b に変更を加えることで、PHPが新しいメモリ領域に$b用のコピーを作成する
$b[0] = 'b';
echo "\$b に変更を加えた後のメモリ使用量: " . memory_get_usage() . " バイト\n";
// ここで$bのために新たに約1MBメモリが確保されるため、合計で約2MB分のメモリが使われる
// 4. COWによるメモリ解放の瞬間
// ここで、元の変数 $a を NULL に設定して破棄する
$a = null;
echo "\$a を NULL に設定した後のメモリ使用量: " . memory_get_usage() . " バイト\n";
// $a が参照していた元のメモリ領域の参照カウントが 0 になるため、
// ガベージコレクタによってそのメモリ領域が解放される。
// メモリ使用量が約1MB分減少し、最終的に$bが使っている約1MB分だけになる。
// 5. スクリプト終了
unset($b);
echo "\$b を unset した後のメモリ使用量: " . memory_get_usage() . " バイト\n";
// $b のメモリも解放され、開始時の値に近くなる
}
}
echo "<pre>";
$cls1 = new test1();
$cls1->test1();
$cls1->test2();
echo "</pre>";
//[実行例]
/*
スクリプト開始時のメモリ使用量: 428008 バイト
$a 作成後のメモリ使用量: 1480680 バイト
$b = $a 実行後のメモリ使用量: 1480680 バイト
$b に変更を加えた後のメモリ使用量: 2533352 バイト
$a を NULL に設定した後のメモリ使用量: 1480680 バイト
$b を unset した後のメモリ使用量: 428008 バイト
*/
class test1
{
function test1()
{
//At the time a string is set to $a, one piece of data exists (reference count: 1)
$a = "init";
echo "(1) Memory usage: " . memory_get_usage() . " bytes\n"; //(1) Memory usage: (Example) 429472 bytes
//At this point, $a and $b reference the same memory area (reference count: 2)
$b = $a;
echo "(2) Memory usage: " . memory_get_usage() . " bytes\n"; //(2) Memory usage: (Example) 429472 bytes
//$a, $b, and $c reference the same memory area (reference count: 3)
$c = $a;
echo "(3) Memory usage: " . memory_get_usage() . " bytes\n"; //(3) Memory usage: (Example) 429472 bytes
// At this point, a new memory area is allocated for $b and the data is copied.
// $a and $c continue to reference the original memory area.
$b .= " add";
echo "(4) Memory usage: " . memory_get_usage() . " bytes\n"; // (4) Memory usage: (Example) 429512 bytes
}
function test2()
{
// [Freeing memory using COW]
echo "Memory usage at script start: " . memory_get_usage() . " bytes\n";
// 1. Create a large string
$a = str_repeat('a', 1024 * 1024); // 1MB string
echo "Memory usage after $a creation: " . memory_get_usage() . " bytes\n";
// This adds approximately 1MB of memory.
// 2. Assignment using COW (memory sharing)
$b = $a;
// No new memory is allocated at this point (only the reference count increases).
echo "Memory usage after executing \$b = \$a: " . memory_get_usage() . " bytes\n";
// Memory usage remains almost unchanged.
/ 3. Cancel COW (write occurs)
/ By making changes to $b, PHP creates a copy of $b in a new memory area.
$b[0] = 'b';
echo "Memory usage after making changes to \$b: " . memory_get_usage() . " bytes\n";
/ At this point, approximately 1MB of new memory is allocated for $b, for a total of approximately 2MB of memory used.
/ 4. The moment memory is freed by COW.
/ Here, the original variable $a is set to NULL to discard it.
$a = null;
echo "Memory usage after setting \$a to NULL: " . memory_get_usage() . " bytes\n";
/ $a The reference count of the original memory area referenced by becomes 0,
// so the garbage collector frees that memory area.
// Memory usage decreases by about 1 MB, and finally only about 1 MB is used by $b.
// 5. Script End
unset($b);
echo "\Memory usage after unsetting $b: " . memory_get_usage() . " bytes\n";
// The memory for $b is also freed, returning it to its starting value.
}
}
echo "<pre>";
$cls1 = new test1();
$cls1->test1();
$cls1->test2();
echo "</pre>";
//[Execution Example]
/*
Memory usage at script start: 428008 bytes
Memory usage after creating $a: 1480680 bytes
Memory usage after executing $b = $a: 1480680 bytes
Memory usage after modifying $b: 2533352 bytes
Memory usage after setting $a to NULL: 1,480,680 bytes
Memory usage after unsetting $b: 428,008 bytes
*/
class test2
{
function test()
{
$a = 100;
$this->test2($a);
$a = null;
unset($a);
$a =100;
}
private function test2(int $num):int
{
return $num++;
}
}
echo "<pre>";
$cls2 = new test2();
$cls2->test();
echo "</pre>";
class test2
{
function test()
{
$a = 100;
$this->test2($a);
$a = null;
unset($a);
$a =100;
}
private function test2(int $num):int
{
return $num++;
}
}
echo "<pre>";
$cls2 = new test2();
$cls2->test();
echo "</pre>";
| 著作権情報 |
| ホームページおよプリ等に掲載されている情報等については、いかなる保障もいたしません。 ホームページおよびアプリ等を通じて入手したいかなる情報も複製、販売、出版または使用させたり、 または公開したりすることはできません。 当方は、ホームページおよびアプリ等を利用したいかなる理由によっての障害等が発生しても、 その結果ホームページおよびアプリ等を利用された本人または他の第三者が被った損害について 一切の責任を負わないものとします。 |