コンテンツにスキップ

パフォーマンス: メモリ断片化アナライザー

Performance モジュールは、意図的に小さな構成になっています。これは、エンジン処理でマークした区間全体のピークメモリと保持メモリを測定する、単一の観測専用ツール — MemoryFragmentationAnalyzer — です。このサーフェスには、ツールが生成するイミュータブルなスナップショットも含まれます。バジェットの強制、スロットリング、エンジン動作の変更は行いません。

スコープと安定性。 このモジュールの実際のサーフェスは 2 つのクラス (MemoryFragmentationAnalyzerMemoryFragmentationSnapshot) です。これは、操作ごとのバジェット強制ハーネスではありませんperformance_budget の値は各モジュールのフロントマターで使うドキュメント上の慣例であり、 このモジュールが強制するものではありません。このサーフェスは experimental です。これは診断ツールであり、 @since 3.2.0 で導入されました。スナップショットの形状は今後変更される可能性があります。

Terminal window
composer require nextpdf/core:^3

リソース使用率は、PDF エンジンにとって第一級の品質関心事です。そのために最低限観測すべきなのは、ピーク メモリ(ウィンドウ中の最高水準)と 保持 メモリ(ウィンドウ終了後もなお保持されているもの)を分離して捉えることです。このモジュールは、まさにそれだけを測定し、それ以上のことは行いません。

MemoryFragmentationAnalyzer は観測専用であり、ライターやドキュメントの状態を変更しません。reset() は GC サイクルを実行し、PHP のピークカウンターをリセットするため、以降の測定をリセット後のウィンドウに帰属できます。mark(string $label) は、ラベル付けされた地点で MemoryFragmentationSnapshot を取得します。snapshots() は、取得済みの系列を返します。peakDelta()retainedDelta() は、実行全体にわたるピークと保持の変化を報告します。

MemoryFragmentationSnapshotfinal readonly な値オブジェクトです。ラベル付けされた地点を表し、transientBytes()(ピークから保持を引いた値 — 使用後に解放されたメモリ)、retentionRatio()(ピークに対する保持の比率)、およびエクスポート用の toArray() を備えています。transient-bytes の値が高く、保持比率が低い場合は、バッファ再利用戦略で取り除ける可能性のあるチャーン(入れ替わり)を示します。どちらのクラスも @since 3.2.0 です。

クラス主なメンバー役割
MemoryFragmentationAnalyzerreset(), mark(string $label), snapshots(), peakDelta(), retainedDelta()観測専用のメモリアナライザー (@since 3.2.0)
MemoryFragmentationSnapshottransientBytes(), retentionRatio(), toArray()イミュータブルなラベル付き測定値 (@since 3.2.0)

完全な PHPDoc テーブルを取得するには composer docs:generate-api-php -- --module=Performance を実行してください。

ホットパスを囲んで、デルタを読み取ります。

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Performance\MemoryFragmentationAnalyzer;
$analyzer = new MemoryFragmentationAnalyzer();
$analyzer->reset();
$analyzer->mark('before-write');
// ... engine work under observation ...
$analyzer->mark('after-write');
printf("Peak delta: %d B, retained delta: %d B\n", $analyzer->peakDelta(), $analyzer->retainedDelta());

レンダリングをラップし、断片化スナップショットをメトリクスシンクへ送出します。transient bytes が高い一方で保持比率が低い場合は、チャーンのシグナルとして扱います。

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Performance\MemoryFragmentationAnalyzer;
use Psr\Log\LoggerInterface;
final readonly class RenderMemoryProbe
{
public function __construct(private LoggerInterface $logger) {}
/** @param callable():void $render The render closure to observe. */
public function observe(callable $render): void
{
$analyzer = new MemoryFragmentationAnalyzer();
$analyzer->reset();
$analyzer->mark('start');
$render();
$analyzer->mark('end');
foreach ($analyzer->snapshots() as $snapshot) {
$this->logger->info('mem-frag', $snapshot->toArray());
}
}
}
  • reset()gc_collect_cycles()memory_reset_peak_usage() を呼び出します。これは PHP のピークカウンターにプロセス全体で影響します。同じリクエスト内でピークカウンターを読み取る別のコンポーネントと交互に使用しないでください。
  • 測定値は、最後の reset() 以降のウィンドウに帰属します。先行する reset() なしで mark() を呼び出すと、プロセス開始時点から測定されるため、通常これは望ましい結果ではありません。
  • これは診断ツールであり、制御機構ではありません。処理をスロットリングしたり中断したりすることは決してありません。これに依存してバックプレッシャーを構築しないでください。
  • 再現性プロファイルは structural です。バイト数は、ランタイム、アロケーター、GC の状態に依存します。同じ論理的な処理であっても、2 回の実行は数値的に異なります。

アナライザー自体のオーバーヘッドは、reset() 時の GC サイクルと、mark() ごとの hrtime() / memory_get_* の読み取りです。つまり、観測対象の処理と比べれば無視できる程度です。mark() ごとに小さなスナップショットを 1 つ割り当てます。このフロントマターの performance_budget はドキュメント全体での参照値であり、このモジュールはこれを強制しません。

メモリの数値は診断データです。これらにドキュメントの内容は含まれませんが、きめ細かなメモリプロファイルから入力のサイズや形状に関する情報が漏れる可能性があります。スナップショットのエクスポートは内部テレメトリーとして扱い、外部に共有する前にプロジェクトのログスクラブ義務を適用してください。このモジュールは I/O を行わず、外部データを埋め込みません。エンジンの脅威モデルについては /modules/core/security/ を参照してください。

このモジュールは、PDF 仕様に関する規範的な主張を一切行いません。これはメモリ診断ツールであり、条項の引用が必要な標準化されたプロトコルを実装しているものではありません。アーキテクチャ上の根拠として、ISO/IEC/IEEE 42010 アーキテクチャ記述フレームワークにおけるリソース使用率の品質ビューを参照していますが、これはアーキテクチャ実践との整合であり、PDF の引用ではありません。エンジンの適合性は、/modules/core/conformance/ に記載されたオラクルおよびゴールデンスイートによって検証されます。