성능: 메모리 단편화 분석기
한눈에 보기
섹션 제목: “한눈에 보기”성능 모듈은 의도적으로 작게 설계되었습니다. 이 모듈은 관찰 전용 도구 하나, 즉 MemoryFragmentationAnalyzer로 구성되며, 엔진 작업에서 표시한 구간의 최대 메모리와 잔류 메모리를 측정합니다. 이 표면에는 도구가 생성하는 불변 스냅샷도 포함됩니다. 예산을 강제하거나, 작업 속도를 제한하거나, 엔진 동작을 변경하지 않습니다.
범위 및 안정성. 이 모듈의 실제 표면은 두 개의 클래스입니다 (
MemoryFragmentationAnalyzer,MemoryFragmentationSnapshot). 이는 작업별 예산 강제 하니스가 아닙니다.performance_budget값은 모든 모듈의 프런트매터에 있는 문서화 관례이며, 이 모듈이 강제하는 값이 아닙니다. 이 표면은experimental상태입니다. 진단 도구로@since 3.2.0에 도입되었습니다. 스냅샷 형태는 변경될 수 있습니다.
composer require nextpdf/core:^3개념 개요
섹션 제목: “개념 개요”PDF 엔진에서 리소스 사용량은 일급 품질 관심사입니다. 이를 뒷받침하는 최소한의 관찰 대상은 최대 메모리(구간 동안의 최고 수위)와 잔류 메모리(구간이 끝난 후에도 남아 있는 메모리)를 구분하는 것입니다. 이 모듈은 정확히 그것만 측정하며 그 이상은 측정하지 않습니다.
MemoryFragmentationAnalyzer는 관찰 전용입니다. 작성기나 문서 상태를 변경하지 않습니다. reset()은 GC 사이클을 실행하고 PHP의 최대값 카운터를 재설정하여, 이후 측정값이 재설정 이후 구간에 귀속되도록 합니다. mark(string $label)는 레이블이 지정된 지점에서 MemoryFragmentationSnapshot를 캡처합니다. snapshots()는 캡처된 시계열을 반환합니다. peakDelta()와 retainedDelta()는 실행 전반에 걸친 최대 메모리와 잔류 메모리의 변화를 보고합니다.
MemoryFragmentationSnapshot은 final readonly 값 객체입니다. 레이블이 지정된 지점이며, transientBytes()(최대값에서 잔류값을 뺀 값 — 사용되었다가 해제된 메모리), retentionRatio()(잔류값 대비 최대값 비율), 내보내기용 toArray()를 제공합니다. 높은 일시적 바이트 수치와 낮은 잔류 비율은 버퍼 재사용 전략으로 제거할 수 있는 변동(churn)을 나타냅니다. 두 클래스 모두 @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) |
전체 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());코드 예제 — 프로덕션
섹션 제목: “코드 예제 — 프로덕션”렌더링을 감싸 단편화 스냅샷을 메트릭 싱크로 내보내고, 높은 일시적 바이트와 낮은 잔류 비율이 함께 나타나는 상황을 변동(churn) 신호로 취급합니다.
<?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 상태에 따라 달라집니다. 동일한 논리적 작업이라도 두 번의 실행은 수치상 다릅니다.
분석기 자체의 오버헤드는 reset() 시의 GC 사이클과 mark()당 hrtime() / memory_get_* 읽기 한 번, 즉 관찰 대상 작업에 비해 무시할 수 있는 수준입니다. mark()당 작은 스냅샷 하나를 할당합니다. 이 프런트매터의 performance_budget는 문서 전반의 참조 수치이며, 이 모듈은 이를 강제하지 않습니다.
보안 참고사항
섹션 제목: “보안 참고사항”메모리 수치는 진단 데이터입니다. 문서 내용을 포함하지는 않지만, 세분화된 메모리 프로파일은 입력의 크기와 형태에 관한 정보를 누출할 수 있습니다. 스냅샷 내보내기를 내부 텔레메트리로 취급하고, 외부에 공유하기 전에 프로젝트의 로그 스크러빙 의무를 적용하십시오. 이 모듈은 I/O를 수행하지 않으며 외부 데이터를 포함하지 않습니다. /modules/core/security/에 있는 엔진 위협 모델을 참조하십시오.
적합성
섹션 제목: “적합성”이 모듈은 PDF 명세에 대한 규범적 주장을 단언하지 않습니다. 이것은 메모리 진단 도구이며, 절(clause)을 인용해야 하는 표준화된 프로토콜을 구현하지 않습니다. 아키텍처상 근거는 ISO/IEC/IEEE 42010 아키텍처 기술 프레임워크의 리소스 사용량 품질 관점을 참조합니다. 이는 PDF 인용이 아니라 아키텍처 실무와의 정합성입니다. 엔진 적합성은 /modules/core/conformance/에 설명된 오라클 및 골든 스위트로 검증됩니다.