性能:内存碎片分析器
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 模块 —— 内存观测的常见对象。
- 引擎安全模型