Przejdź do głównej zawartości

Wydajność: analizator fragmentacji pamięci

Moduł Performance ma ściśle określony zakres. Udostępnia jedno narzędzie wyłącznie obserwacyjne, MemoryFragmentationAnalyzer, które mierzy szczytowe i zatrzymane zużycie pamięci w oznaczonych oknach pracy silnika. Publiczny interfejs obejmuje też niezmienną migawkę tworzoną przez to narzędzie. Nie egzekwuje budżetów, nie ogranicza pracy ani nie zmienia zachowania silnika.

Zakres i stabilność. Rzeczywisty interfejs tego modułu obejmuje dwie klasy (MemoryFragmentationAnalyzer, MemoryFragmentationSnapshot). Nie jest szkieletem egzekwowania budżetu dla poszczególnych operacji. Wartość performance_budget we frontmatterze każdego modułu jest konwencją dokumentacyjną, a nie wartością, którą ten moduł egzekwuje. Interfejs jest experimental: to narzędzie diagnostyczne wprowadzone w @since 3.2.0. Struktura migawki może ulec zmianie.

Okno terminala
composer require nextpdf/core:^3

Wykorzystanie zasobów jest jednym z kluczowych aspektów jakości silnika formatu Portable Document Format (PDF). Minimalnym obserwowanym rozróżnieniem jest podział na pamięć szczytową (maksymalny poziom w trakcie okna) i pamięć zatrzymaną (to, co pozostaje zajęte po zakończeniu okna). Ten moduł mierzy wyłącznie to.

MemoryFragmentationAnalyzer wyłącznie obserwuje; nie zmienia stanu obiektu writer ani dokumentu. reset() uruchamia cykl odśmiecania pamięci (GC) i zeruje licznik szczytu w PHP, dzięki czemu kolejne pomiary mieszczą się w oknie liczonym od momentu zerowania. mark(string $label) przechwytuje obiekt MemoryFragmentationSnapshot w oznaczonym punkcie. snapshots() zwraca przechwyconą serię. peakDelta() oraz retainedDelta() raportują zmianę pamięci szczytowej i zatrzymanej w trakcie całego przebiegu.

MemoryFragmentationSnapshot jest obiektem wartości final readonly: oznaczonym punktem z metodami transientBytes() (szczyt minus zatrzymana, czyli pamięć, która została użyta i zwolniona), retentionRatio() (stosunek pamięci zatrzymanej do szczytowej) oraz toArray() do eksportu. Wysoka liczba bajtów tymczasowych przy niskim współczynniku zatrzymania wskazuje na zbędną rotację pamięci, którą mogłaby wyeliminować strategia ponownego wykorzystania buforów. Obie klasy mają oznaczenie @since 3.2.0.

KlasaKluczowe składoweRola
MemoryFragmentationAnalyzerreset(), mark(string $label), snapshots(), peakDelta(), retainedDelta()Wyłącznie obserwacyjny analizator pamięci (@since 3.2.0)
MemoryFragmentationSnapshottransientBytes(), retentionRatio(), toArray()Niezmienny, oznaczony pomiar (@since 3.2.0)

Uruchom composer docs:generate-api-php -- --module=Performance, aby wygenerować pełną tabelę PHPDoc.

Dodaj instrumentację do gorącej ścieżki, a następnie odczytaj różnice.

<?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());

Opakuj renderowanie i wyemituj migawkę fragmentacji do odbiornika metryk. Niski współczynnik zatrzymania przy dużej liczbie bajtów tymczasowych traktuj jako sygnał nadmiernej rotacji pamięci.

<?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() wywołuje gc_collect_cycles() oraz memory_reset_peak_usage(). Ma to skutek globalny dla całego procesu w odniesieniu do licznika szczytu w PHP. Nie przeplataj tego wywołania z działaniem innego komponentu, który odczytuje ten sam licznik w tym samym żądaniu.
  • Pomiary odnoszą się do okna liczonego od ostatniego wywołania reset(). Wywołanie mark() bez poprzedzającego reset() mierzy od początku procesu, co zwykle nie jest tym, czego oczekujesz.
  • To narzędzie diagnostyczne, a nie mechanizm sterujący. Nigdy nie ogranicza ani nie przerywa pracy. Nie buduj na nim mechanizmu przeciwciśnienia.
  • Profil odtwarzalności ma wartość structural: wartości w bajtach zależą od środowiska uruchomieniowego, alokatora oraz stanu GC. Dwa przebiegi mogą różnić się liczbowo nawet przy tej samej logicznej pracy.

Narzut samego analizatora to cykl odśmiecania pamięci przy reset() oraz jeden odczyt hrtime() / memory_get_* na każde mark(), co jest pomijalne w stosunku do obserwowanej pracy. Alokuje jedną małą migawkę na każde mark(). Wartość performance_budget w tym frontmatterze jest wartością odniesienia dla całej dokumentacji; ten moduł jej nie egzekwuje.

Wartości dotyczące pamięci są danymi diagnostycznymi. Nie zawierają treści dokumentu, jednak szczegółowy profil pamięci może ujawnić rozmiar i kształt danych wejściowych. Eksporty migawek traktuj jako telemetrię wewnętrzną i przed udostępnieniem ich na zewnątrz zastosuj obowiązującą w projekcie procedurę czyszczenia logów. Moduł nie wykonuje żadnych operacji input/output (I/O) ani nie osadza żadnych danych zewnętrznych. Zobacz model zagrożeń silnika w /modules/core/security/.

Ten moduł nie formułuje żadnych normatywnych twierdzeń wobec specyfikacji PDF. Jest narzędziem diagnostycznym pamięci i nie implementuje żadnego ustandaryzowanego protokołu, którego klauzule można by przywołać. Jego uzasadnienie architektoniczne odwołuje się do widoku jakości w zakresie wykorzystania zasobów z ram opisu architektury ISO/IEC/IEEE 42010. To odwołanie oznacza zgodność z praktyką architektoniczną, a nie cytat ze specyfikacji PDF. Zgodność silnika jest weryfikowana przez zestawy oracle i golden opisane w /modules/core/conformance/.