メモリ管理とパフォーマンスのヒント
早めにメモリを解放し、大きな配列のコピーを避け、巨大なデータセットにはジェネレーターを使います
「メモリ管理とパフォーマンスのヒント」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。
PHPのメモリ管理
PHPは、ガベージコレクションに循環参照コレクターを備えた参照カウント方式を使用します。各リクエストは新しいヒープで開始しますが、長時間実行されるプロセス(ワーカーやHorizon)ではメモリリークが蓄積することがあります。
memory_limit
php.iniで適切なメモリ制限を設定します。制限を超えると致命的なエラーが発生します。
# php.ini:
memory_limit = 256M
// Check at runtime:
echo memory_get_usage(true) / 1024 / 1024 . " MB";
echo memory_get_peak_usage(true) / 1024 / 1024 . " MB peak";大きな変数のUnset
長い関数内で大きな配列やオブジェクトが不要になったら、明示的にメモリを解放します。
<?php
$data = loadLargeDataset();
processData($data);
unset($data); // free immediately, do not wait for end of scope
gc_collect_cycles(); // force garbage collection if circular references大規模データセットに対するジェネレーター
ジェネレーターを使用すると、大きなファイルやクエリ結果をすべてメモリに読み込まず、1行ずつ処理できます。
<?php
function readCsvLines(string $file): Generator {
$fh = fopen($file, "r");
while (($line = fgetcsv($fh)) !== false) {
yield $line;
}
fclose($fh);
}
foreach (readCsvLines("large.csv") as $row) {
importRow($row);
}大きな配列のコピーを避ける
PHPは配列にコピーオンライトを使用します。配列を変数に代入しても、どちらかが変更されるまでコピーは作成されません。変更が必要な場合は、大きな配列を参照渡しします。
<?php
function processArray(array &$data): void {
// & avoids a copy when the parameter is modified
}ループ内での文字列連結
非常に長い文字列をループ内で連結して構築するのは非効率です。配列とimplode()を使用します。
<?php
// Slow for large N:
$str = "";
foreach ($items as $item) $str .= $item->format()."\n";
// Faster:
$parts = [];
foreach ($items as $item) $parts[] = $item->format();
$str = implode("\n", $parts);オブジェクト生成のキャッシュ
オブジェクトのインスタンス化(特にコンストラクター処理を伴うもの)を高頻度ループ内で行うと、コストがかかります。可能な場合はインスタンスをキャッシュするか、フライウェイトオブジェクトを使用します。
関数の繰り返し呼び出しを避ける
結果が反復ごとに変わらない関数呼び出しは、ループの外に移動します。
<?php
// Slow:
for ($i = 0; $i < count($items); $i++) { ... }
// Fast (count() called once):
$n = count($items);
for ($i = 0; $i < $n; $i++) { ... }PHP-FPMワーカーのチューニング
使用可能なメモリと想定される同時実行数に基づいて、PHP-FPMワーカー数を設定します。大まかな目安は、workers = RAM /(ワーカー1つあたりの平均メモリ使用量)です。
OPcacheとプリロード
OPcache(前のレッスンで扱いました)を有効にし、頻繁に使用するフレームワーククラスをプリロードします。これにより、リクエストごとに発生する解析とコンパイルのオーバーヘッドをなくせます。
まずプロファイリング
最適化する前に、必ずプロファイリングを行います。ボトルネックではないコードにマイクロ最適化を適用すると、時間を浪費し、可読性も低下します。XdebugまたはBlackfireを使用して、実際に処理時間が集中している箇所を見つけます。
まとめ
大規模なデータセットにはジェネレーターを使用します。不要になった変数はunsetします。大きな配列のコピーを避けます。一定の呼び出しはループの外に移動します。最適化する前にXdebugでプロファイリングを行い、実際のボトルネックを見つけます。
確認問題
大規模なデータセットでPHPジェネレーターを使う主な利点は何ですか?
よくある質問
「メモリ管理とパフォーマンスのヒント」レッスンは無料ですか?
はい。「メモリ管理とパフォーマンスのヒント」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。
「メモリ管理とパフォーマンスのヒント」で何を学びますか?
早めにメモリを解放し、大きな配列のコピーを避け、巨大なデータセットにはジェネレーターを使います ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
PHP Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「メモリ管理とパフォーマンスのヒント」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPHP Academyレッスンでコードを書いて実行できますか?
はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- XdebugでPHPをプロファイリングする
- OPcache:バイトコードキャッシュ
- データベースクエリの最適化
- メモリ管理とパフォーマンスのヒント