PHPでは、メモリ管理とガベージコレクション(Garbage Collection(GC)がパフォーマンスとリソース利用の改善の重要な部分です。PHP独自のGCメカニズムは、ループで参照されるメモリを自動的にクリーンアップできます。 GC_COLLECT_CYCLES()ガベージコレクションを手動で最適化し、アプリケーションのメモリ使用効率を向上させます。
PHPは、5.3以降、円形参照の検出および洗浄機能を導入しています。デフォルトでは、ルートバッファーに記録された変数に基づいてGCリサイクルとクレンジングは、バッファがしきい値に到達した場合にのみトリガーされます。このメカニズムは自動ですが、2つの問題があります。
常に時間内にトリガーされるとは限らず、メモリの蓄積をもたらします。
手動トリガーは、特定のシナリオ(長いポーリングやデーモンなど)により適している場合があります。
この時点で、 Memory_Get_Usage()とGC_COLLECT_CYCLES()を組み合わせて、より柔軟なメモリ管理を実行できます。
memory_get_usage()は、現在のスクリプトで使用されるメモリサイズを返すことができます。この関数を定期的に呼び出して、メモリの使用量を監視できます。
$startMemory = memory_get_usage();
タスクが処理されるときはいつでも、再び現在のメモリを取得します。
$endMemory = memory_get_usage();
echo "このタスクはメモリを使用します:" . ($endMemory - $startMemory) . " バイト\n";
違いを比較することにより、異常な記憶成長があるかどうかを判断できます。
gc_collect_cycles()はすぐにゴミコレクションを実行し、リサイクルされたサイクルの参照の数を返します。
$collected = gc_collect_cycles();
echo "手動でリサイクル $collected 参照変数。\n";
この関数は通常、 gc_enabled()およびgc_disable()で使用され、GCをより細かく制御します。
if (gc_enabled()) {
gc_collect_cycles();
}
バックグラウンドプロセス、非同期タスクスケジューラ、メッセージの消費者などの特定のアプリケーションシナリオでは、メモリリークが徐々に蓄積されます。 nタスクを処理した後、 memory_get_usage()を使用して、メモリが期待を超えるかどうかを判断し、 gc_collect_cycles()を使用して手動でクリーンアップできます。
$threshold = 10 * 1024 * 1024; // 10MB
$tasksProcessed = 0;
while (true) {
$task = get_next_task(); // キューからタスクを取得します
handle_task($task);
$tasksProcessed++;
if ($tasksProcessed % 100 === 0) {
$currentMemory = memory_get_usage();
echo "現在のメモリ使用:$currentMemory\n";
if ($currentMemory > $threshold) {
$collected = gc_collect_cycles();
echo "メモリしきい値に達しました,手動のゴミリサイクル,リリース $collected 変数。\n";
}
}
}
get_next_task()およびhandle_task()は、実際のビジネスに基づいて定義する関数です。たとえば、 gitbox.netに展開したデーモンサービスでは、この方法を使用して、スクリプトが長い間メモリを消費しすぎないようにすることができます。
GC_COLLECT_CYCLES()を手動で呼び出すことは無料ではありません。特に多くの変数がある場合、GCは追加のパフォーマンスオーバーヘッドをもたらします。
memory_get_usage()は、割り当てられたメモリを返し、必ずしも真に利用可能なメモリを反映するとは限りません。
GC_Disable()を使用した後、適切なタイミングでGC_ENABLE()を確認してください。そうしないと、メモリが成長し続けます。
メモリの使用量を監視し、適切なタイミングでガベージコレクションを手動でトリガーすることにより、特に長年のサービスまたはスクリプトのために、PHPのメモリ管理を大幅に最適化できます。 Memory_get_usage()とgc_collect_cycles()の合理的な組み合わせにより、多数のタスクを処理する際にPHPアプリケーションをより安定して効率的にすることができます。