效能:記憶體碎片分析器
Performance 模組刻意維持精簡。它提供一個僅供觀測的工具——MemoryFragmentationAnalyzer——可在引擎工作中已標記的各個區間量測尖峰與保留記憶體。這個介面也包含該工具產生的不可變快照。它不會強制套用預算、不會節流,也不會改變引擎行為。
範圍與穩定性。 本模組的實際介面只有兩個類別 (
MemoryFragmentationAnalyzer、MemoryFragmentationSnapshot)。它並非 用來對逐項操作強制套用預算的工具。performance_budget值在每個模組的 front-matter 中是一種文件慣例,而非本模組會強制套用的設定。這個介面是experimental:它是於@since 3.2.0引入的診斷工具。其快照結構可能會演進。
composer require nextpdf/core:^3概念綜覽
標題為「概念綜覽」的區段對 PDF 引擎而言,資源使用率是首要品質考量。支撐這項考量的最小可觀測量,是區分尖峰記憶體(區間內的最高水位)與保留記憶體(區間結束後仍佔用的部分)。本模組精準量測這一點,不多做其他事。
MemoryFragmentationAnalyzer 僅供觀測——它不會變更 writer 或文件狀態。reset() 會執行一次 GC 循環並重設 PHP 的尖峰計數器,讓後續量測都歸屬於重設後的區間。mark(string $label) 會在帶有標籤的點擷取一份 MemoryFragmentationSnapshot。snapshots() 會回傳已擷取的資料序列。peakDelta() 與 retainedDelta() 會回報整個執行過程中尖峰與保留記憶體的變化量。
MemoryFragmentationSnapshot 是一個 final readonly 值物件:代表一個帶有標籤的量測點,包含 transientBytes()(尖峰減去保留——曾被使用後又釋放的記憶體)、retentionRatio()(保留除以尖峰),以及供匯出使用的 toArray()。暫態位元組數值偏高但保留比率偏低,代表存在頻繁的記憶體周轉,而緩衝區重用策略有機會消除這種周轉。這兩個類別皆為 @since 3.2.0。
API 介面
標題為「API 介面」的區段| 類別 | 主要成員 | 職責 |
|---|---|---|
MemoryFragmentationAnalyzer | reset(), mark(string $label), snapshots(), peakDelta(), retainedDelta() | 僅供觀測的記憶體分析器(@since 3.2.0) |
MemoryFragmentationSnapshot | transientBytes(), retentionRatio(), toArray() | 不可變的帶標籤量測值(@since 3.2.0) |
執行 composer docs:generate-api-php -- --module=Performance 即可取得完整的 PHPDoc 表格。
程式碼範例——快速入門
標題為「程式碼範例——快速入門」的區段在熱路徑前後加上標記,再讀取各項變化量。
<?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());程式碼範例——正式環境
標題為「程式碼範例——正式環境」的區段包覆一次算繪流程,並將碎片快照送往指標接收端,把高暫態位元組且低保留比率的情況視為記憶體周轉訊號。
<?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()以來的區間。若mark()之前沒有先呼叫reset(),量測就會從行程啟動算起,這通常並非你想要的結果。 - 這是一項診斷工具,並非控制機制。它絕不會節流或中止工作;請勿據此建立回壓機制。
- 其可重現性類型為
structural:位元組數值取決於執行階段、配置器與 GC 狀態。即使是相同的邏輯工作,兩次執行的數值也會不同。
分析器本身的額外負擔,是在 reset() 時執行一次 GC 循環,以及每次 mark() 進行一次 hrtime() / memory_get_* 讀取——相較於它所觀測的工作量微不足道。每次 mark() 會配置一份小型快照。此 front-matter 中的 performance_budget 是整份文件通用的參考數值;本模組並不會強制套用它。
安全性注意事項
標題為「安全性注意事項」的區段記憶體數值屬於診斷資料。它們並不包含文件內容,但細緻的記憶體剖析可能會洩漏與輸入大小及結構相關的資訊。請將快照匯出視為內部遙測資料,並在對外分享前,先依專案的日誌清理義務加以處理。本模組不執行任何 I/O,也不嵌入任何外部資料。請參閱 /modules/core/security/ 中的引擎威脅模型。
一致性
標題為「一致性」的區段本模組並未主張任何具 PDF 規範性的規格聲明。它是一項記憶體診斷工具,並未實作任何需要引用條款的標準化協定。其架構理據參考了 ISO/IEC/IEEE 42010 架構描述框架中的資源使用率品質觀點,這屬於架構實務上的對齊,而非 PDF 引用。引擎一致性是由 /modules/core/conformance/ 中所述的 oracle 與 golden 測試套件驗證的。
另請參閱
標題為「另請參閱」的區段- Observability 模組 — 更廣泛的執行階段狀態介面。
- Telemetry 模組 — 將指標發送至外部後端。
- Writer 模組 — 記憶體觀測的常見對象。
- 引擎安全模型