《PHP8上級試験対策》Copy on Write(コピーオンライト)の仕組みとメモリ管理

  • URLをコピーしました!
目次

はじめに

PHPの配列や文字列は、代入や関数の引数で渡すときにいきなりメモリをコピーするわけではありません
この仕組みは「Copy on Write(COW)」と呼ばれ、PHPのメモリチューニングの基本概念の一つです。

本記事では、COWの挙動をコード例とメモリ確認で解説し、上級試験で押さえておきたいポイントをまとめます。

キーワード:Copy on Write / COW / memory_get_usage / 配列 / 文字列 / 値渡し / 参照カウント / PHPメモリ管理

コード例と実行結果

<?php
declare(strict_types=1);
error_reporting(-1);

function hoge($arg){
    echo 'in hoge memory_get_usage: ', memory_get_usage(true), "\n";
}

echo 'start memory_get_usage: ', memory_get_usage(true), "\n";

$s = str_repeat('a',1_000_000);
echo '1st memory_get_usage: ', memory_get_usage(true), "\n";

$ss = $s;
echo '2st memory_get_usage: ', memory_get_usage(true), "\n";

hoge($s);

正しい出力例(環境によって多少差があります)

start memory_get_usage: 2097152
1st memory_get_usage: 12099584
2st memory_get_usage: 12099584
in hoge memory_get_usage: 12099584

挙動の解説

  1. $s = str_repeat('a', 1_000_000);
    → 文字列データを生成し、メモリに確保。
  2. $ss = $s;
    → データはコピーされず、同じメモリ上の文字列を参照
    → この時点ではメモリ使用量は増えない。
  3. hoge($s)
    → 関数に渡す際もコピーは行われず、同じデータを参照。
    → 変更がなければメモリ使用量は変わらない。
  4. Write(書き込み)が発生した場合に初めてコピーされる
    → COW(Copy on Write)の本質。

ASCII図解:Copy on Write

代入直後(Copy on Write 前)
┌────────────────────┐
│ 実データ "aaaa..."  │ ← 1MB
└────────────────────┘
     ▲        ▲        ▲
     │        │        │
   $s      $ss     hoge($s)
 (参照カウント3)

いずれも同じデータを指している!

書き換えが発生した瞬間にコピー
$ss[0] = 'b';   ← ここで新しいメモリ確保

上級試験で押さえておくポイント

  • 代入や引数渡しでメモリは増えない
  • 変更(Write)時に初めてコピーされる
  • memory_get_usage() で確認しても、COWにより増えないことがある
  • Copy on Write は大きな配列や文字列を扱う際のメモリ節約の基本

この記事が気に入ったら
いいねしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次