Mange hjemmesider fejler på grund af PHP Memory Limit, selvom der ikke vises nogen fejl. Jeg viser, hvordan disse usynlige nedbrud opstår, hvad der udløser dem, og hvordan jeg med målrettet Indstilling Stoppe hukommelsesfejl pålideligt.
Centrale punkter
- Stille fejl blokerer sider uden synlig meddelelse.
- Grænser fra 64 til 128 MB er ofte ikke længere tilstrækkeligt.
- Plugins og store databaser øger RAM-forbruget.
- Hosting-optimering med FPM og OPcache mindsker risikoen.
- Overvågning afslører flaskehalse tidligt.
Hvad sker der ved hukommelsesudmattelse?
Hvis et script overskrider den tildelte hukommelse, genererer det ofte ikke noget synligt Fejl. I stedet afslutter processen sit arbejde brat og efterlader en hvid skærm eller en blokeret forespørgsel, der ligner en Timeout virker. På delte servere er der ekstra beskyttelsesmekanismer, der afslutter processer før tid. På den måde forhindrer platformen overbelastning, men for dig virker det som en mystisk hængning. Jeg ser så huller i logfilerne, afbrudte anmodninger eller FPM-genstarter, mens den egentlige årsag ligger i RAM-grænsen.
Det er vigtigt at skelne mellem disse to fejl: 504- eller 502-fejl fungerer som klassiske timeouts, men er ofte resultatet af en for tidlig afbrydelse af processen. Det memory_limit gælder pr. anmodning; den reserverer ikke RAM på forhånd, men afslutter hårdt, når grænsen overskrides. Hvis serveren selv kommer i swap, forlænges svartiderne betydeligt, selvom grænsen formelt ikke synes at være nået – i praksis er effekten den samme: Brugere ser hængende eller tomme sider.
Registrer stille fejl uden meddelelse
Silent Errors opstår ofte, fordi produktionssystemer undertrykker fejlmeddelelser og PHP-FPM ved flaskehalse genstarter Worker. Tæt på grænsen starter Garbage Collection oftere og øger Forsinkelse, uden at give en klar meddelelse. Under pres afslutter OOM-Killer processer, før PHP kan skrive en udskrift. I praksis ser jeg 502/503-gateway-fejl, sporadiske hvide skærme og sporadiske tomme logfiler. Hvis du vil forstå, hvordan begrænsninger påvirker responstider, kan du læse de kompakte Performance-effekter af PHP-hukommelsesgrænsen; så kan jeg bedre klassificere symptomerne.
Jeg kontrollerer desuden FPM-slowlogs og FPM-status. Status viser aktive/inaktive arbejdere, gennemsnitlige køretider og aktuelle kø-længder. Hvis „terminated“ eller „out of memory“ hyppigt forekommer i fejllogfilerne, eller hvis slowlog-posterne stiger parallelt med spidsbelastninger, er det en pålidelig indikator. I Nginx- eller Apache-fejllogfiler kan jeg desuden se mønstre i 502/504-fejl, der falder sammen med FPM-genstarter eller pool-overløb.
Typiske årsager i hverdagen
Ressourcekrævende plugins indlæser store Arrays og objekter i hukommelsen; hvis flere af disse kører parallelt, stiger forbruget kraftigt. Billedoptimeringsprogrammer, crawlere, SEO-scannere eller sidebyggere bruger meget hukommelse og holder data længere i RAM end nødvendigt. En database, der gennem årene er vokset med revisioner, transients og spam-kommentarer, forstærker problemet, fordi forespørgsler trækker flere resultater ind i processen. Ved høj belastning, f.eks. i butikker med filtersøgninger, kæmper flere PHP-arbejdere om begrænset hukommelse. Derudover øger mange aktiverede udvidelser det grundlæggende forbrug, så der er lidt plads til ægte forespørgsler.
Særligt kritiske er billed- og PDF-behandling (Imagick/GD), importører, backup-plugins, fuldtekstsøgninger og REST-endpoints, der behandler store JSON-payloads. Cron-jobs (f.eks. indeksgenopbygninger, feeds, synkroniseringer) kører ofte parallelt med besøgende og forårsager dermed uventede spidsbelastninger. I admin-områder tilføjes editor-previews, metabokse og live-valideringer – det forklarer, hvorfor backends oftere er på WP_MAX_MEMORY_LIMIT støder som frontends.
Sådan kontrollerer jeg grænseværdien og det faktiske forbrug
Jeg starter med en kort PHP-info eller en CLI-check for at finde det effektive memory_limit og aktive moduler. I WordPress logger jeg via debug-tilstand ind på peak-hukommelsen pr. anmodning og identificerer, hvilke opkald der bruger særlig meget. For at foretage en hurtig test opretter jeg en testside, deaktiverer plugins i blokke og observerer Toppen ved identisk sideopkald. I hostingpaneler eller via ps/top/wpm undersøger jeg, hvor meget hver FPM-arbejder i gennemsnit bruger. På den måde kan jeg måle flaskehalse og træffe velinformerede beslutninger om den næste grænse.
// Kort test i WordPress (wp-config.php) define('WP_DEBUG', true); define('SCRIPT_DEBUG', true); // Kontroller peak-hukommelse, f.eks. via Query Monitor eller log-udskrifter
For at sikre reproducerbare målinger logger jeg spidsbelastningerne direkte fra PHP. På den måde kan jeg også se i produktionsnære tests, hvor meget de enkelte controllere, hooks eller shortcodes bruger:
// I en MU-plugin-fil eller functions.php: add_action('shutdown', function () { if (function_exists('memory_get_peak_usage')) {
error_log('Peak memory: ' . round(memory_get_peak_usage(true) / 1024 / 1024, 1) . ' MB | URI: ' . ($_SERVER['REQUEST_URI'] ?? 'CLI')); } });
Vigtigt: CLI og FPM bruger ofte forskellige php.ini-filer. Et script, der kører problemfrit via WP-CLI, kan mislykkes i webkonteksten. Derfor tjekker jeg begge kontekster eksplicit (php -i vs. php-fpm) og test om nødvendigt med php -d memory_limit=512M script.php grænserne for et job.
Forøg PHP-hukommelsesgrænsen korrekt
Jeg øger grænsen gradvist og tester efter hvert trin Stabilitet. Først er det ofte nok at øge til 256 MB, men for datakrævende arbejdsopgaver går jeg op på 512 MB og observerer Tinder. Vigtigt: En for høj grænse løser ikke det grundlæggende problem, fordi ineffektive forespørgsler fortsat genererer arbejde. Bemærk også, at FPM-arbejdere ganget med grænsen og antallet af processer hurtigt sprænger den samlede RAM. Derfor kombinerer jeg forhøjelsen med optimeringer af plugins, database og FPM-parametre.
// 1) wp-config.php (før "Det var det, stop med at redigere!") define('WP_MEMORY_LIMIT', '256M');
# 2) .htaccess (før "# END WordPress") php_value memory_limit 256M
; 3) php.ini memory_limit = 256M ; test eventuelt 512M
// 4) functions.php (fallback, hvis nødvendigt) ini_set('memory_limit', '256M');
For admin-opgaver sætter jeg desuden en højere grænse uden at gøre frontend unødigt tungt:
// wp-config.php define('WP_MAX_MEMORY_LIMIT', '512M'); // kun til /wp-admin og bestemte opgaver
Typiske faldgruber: Ved PHP-FPM griber php_value-Direktiver i .htaccess ikke – her bruger jeg .user.ini eller FPM-poolkonfigurationen. Desuden overskriver nogle hostudbydere kundernes indstillinger igen; jeg validerer altid den effektive grænse ved kørselstid (ini_get('memory_limit')). memory_limit = -1 er tabu i produktionen, fordi det ikke længere begrænser lækager eller spidsbelastninger og bringer serveren i knæ.
Hosting-tuning: OPcache, FPM og udvidelser
En holdbar løsning kombinerer en forhøjelse af grænsen med målrettede Indstilling. Jeg dimensionerer OPcache generøst nok til, at hyppigt anvendte scripts forbliver i cachen og der er mindre behov for re-kompilering. I PHP-FPM indstiller jeg pm.max_children, pm.max_requests og pm.memory_limit, så forespørgsler ikke sulter, men serveren har luft. Jeg fjerner unødvendige PHP-udvidelser, fordi de oppuster hver arbejders basishukommelse. På den måde vinder jeg headroom, sænker latenstiden og reducerer risikoen for stille afbrydelser betydeligt.
For OPcache har solide standardindstillinger vist sig at være effektive, som jeg tilpasser afhængigt af kodebasen:
; opcache-anbefalinger opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=20000 opcache.validate_timestamps=1 opcache.revalidate_freq=2
Jeg dimensionerer FPM på baggrund af reelle måleværdier. Som tommelfingerregel gælder: (samlet RAM − OS/tjenester − DB − OPcache) / gennemsnitligt worker-forbrug = pm.max_børn. Eksempel: 8 GB RAM, 1,5 GB OS/daemoner, 2 GB DB, 256 MB OPcache, 180 MB/Worker → (8192−1536−2048−256)/180 ≈ 24, så jeg starter med 20–22 og observerer køen og swappen. pm.max_anmodninger Jeg indstiller den moderat (f.eks. 500–1000) for at stoppe lækager uden at genstarte for ofte. Mellem dynamisk og ondemand Jeg vælger afhængigt af trafikprofilen: ondemand sparer RAM ved sporadiske belastningsspidser, dynamic reagerer hurtigere ved vedvarende belastning.
| Hosting-type | Typisk hukommelsesgrænse | Tuning-funktioner | Brug |
|---|---|---|---|
| Delt basis | 64–128M | Få muligheder | Lille Blogs |
| Administreret WordPress | 256–512M | OPcache, FPM-profiler | Voksende Steder |
| VPS | 512 MB – ubegrænset | Fuld kontrol | Butikker, portaler |
| webhoster.de (testvinder) | op til 768M+ | OPcache & FPM-optimering | YdeevneFokus |
Hold databasen og plugins slanke
Jeg rydder regelmæssigt op i databasen og sletter gamle Revision, slet udløbne transients og ryd op i spam-kommentarer. Rene indekser fremskynder forespørgsler og reducerer hukommelsesbehovet pr. anmodning betydeligt. For plugins vurderer jeg nytteværdi kontra omkostninger og erstatter tunge plugins med lettere alternativer. Cache-plugins og en ren sidecache reducerer dynamiske opkald og sparer RAM under belastning. Denne disciplinerede tilgang begrænser spidsforbruget mærkbart og gør grænserne pålidelige.
Jeg sørger også for, at søgeresultaterne begrænses, og at kun de nødvendige felter indlæses. I WordPress reducerer jeg f.eks. med 'felter' => 'ids' lagerbehovet for store listevisninger betydeligt. Persistente objektcacher aflaster databasen og forkorter anmodningstiderne; det er dog vigtigt ikke at overskride interne in-request-cacher, så der ikke unødigt mange data forbliver i processen.
Forståelse af hukommelsesfragmentering
Selv hvis der synes at være nok RAM, kan fragmentering frigøre Blokke opdele i mange små stykker, som store arrays ikke længere kan rumme. Derfor observerer jeg mønstrene for allokering og frigivelse, især ved billed-, JSON- og søgefunktioner. Kortere anmodninger med klare datalivscyklusser reducerer fragmenteringen. OPcache og optimerede autoload-strategier reducerer også churn i hukommelsen. Hvis du ønsker at dykke dybere ned i emnet, kan du finde baggrundsinformation om Hukommelsesfragmentering og deres effekter på reelle arbejdsbelastninger.
Garbage Collection: Fælder og justeringsskruer
PHP-garbage-collection sparer hukommelse, men kan i grænsetilfælde Spikes udløse. Høje objektgrafer med cyklusser tvinger motoren til hyppige GC-kørsler, hvilket forlænger anmodninger. Jeg reducerer store strukturer, bruger streams i stedet for fuld belastning og lagrer sjældent anvendte data i mellemtrin. I kanttilfælde er det værd at sætte GC på pause for korte opgaver og genaktivere det på en kontrolleret måde. Artiklen giver en praktisk introduktion Optimer garbage collection, der forklarer konkrete justeringsskruer.
Kodningsstrategier mod spidsbelastning
Jeg løser mange lagerproblemer i koden. I stedet for at indlæse store mængder i arrays arbejder jeg med generatorer, paginering og streams. Jeg undgår bredt aggregerede strukturer og skriver funktioner, så mellemresultater kan frigives tidligt.
- Pagination: Opdel store lister i sider, indlæs kun de nødvendige felter.
- Streams/generatorer: Behandle filer og resultater stykke for stykke.
- Chunking: Import/eksport i blokke i stedet for fuld belastning.
- Formatvalg: JSON-strømme i stedet for enorme arrays; hvor det er muligt, iterativ parsing.
- Bevidste livscyklusser: Indstil variabler tidligt, undgå referencer.
// Eksempel: Stream filer i stedet for fuld indlæsning function stream_copy($src, $dst) { $in = fopen($src, 'rb'); $out = fopen($dst, 'wb');
while (!feof($in)) { fwrite($out, fread($in, 8192)); } fclose($in); fclose($out); }
// Eksempel: Behandle store arrays i blokke foreach (array_chunk($bigArray, 500, true) as $chunk) { process($chunk); unset($chunk); }
// WordPress: memory-arme Query
$q = new WP_Query([ 'post_type' => 'product', 'posts_per_page' => 200, 'fields' => 'ids', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ]);
Til billedbehandling vælger jeg bevidst Editor. På systemer med begrænset kapacitet overvejer jeg at skifte, hvis der opstår problemer:
// Omgå Imagick midlertidigt (f.eks. ved høje spidsbelastninger) add_filter('wp_image_editors', function() { return ['WP_Image_Editor_GD', 'WP_Image_Editor_Imagick']; });
Overvågning og logning uden støj
Jeg aktiverer logning med meningsfuld Grænse og registrerer fejl, spidsbelastninger og langsomme anmodninger uden at overbelaste systemet. Query Monitor og FPM-status sider viser mig RAM, eksekveringstid og flaskehalse pr. slutpunkt. I logfiler søger jeg efter mønstre som samtidige 502-fejl, FPM-genstarter eller pludselige afbrydelser. Små belastningstests efter hver ændring giver hurtig feedback om, hvorvidt jeg har truffet den rigtige beslutning. På den måde stopper jeg stille nedbrud, før rigtige besøgende mærker dem.
I praksis har et „basissæt“ vist sig at være effektivt: Aktivér FPM-slowlog, roter fejllogs og indstil hastighedsbegrænsninger for at undgå log-oversvømmelser. I overvågningen korrelerer jeg CPU, RAM, swap, FPM-kø-længde og responstider. Så snart swap vokser eller FPM-køen registrerer, sænker jeg parallelt samtidigheden (færre arbejdere) eller optimerer først de dyreste slutpunkter.
Særlige tilfælde: Admin, CLI, Container
I admin-området er grænserne naturligvis højere – her håndterer jeg mange data, genererer forhåndsvisningsbilleder eller eksporterer lister. Med WP_MAX_MEMORY_LIMIT begrænser jeg dette ekstra målrettet til administratoren. For CLI-opgaver definerer jeg grænser pr. opgave (f.eks. php -d memory_limit=768M), så tunge eksportoperationer kører pålideligt uden at belaste frontend. I containere (cgroups) bemærker jeg, at kernen sætter strenge RAM-grænser; PHP ser godt nok sin memory_limit, men afsluttes alligevel af OOM-killer, hvis containergrænsen overskrides. Derfor stemmer jeg containergrænse, FPM-arbejderantal og memory_limit sammen.
Undgå faldgruber målrettet
- .htaccess-direktiver virker ofte ikke med FPM – bedre
.user.inieller poolkonfiguration. - Forskellige ini-filer til CLI og FPM gør testene inkonsekvente – kontroller altid begge dele.
memory_limitForøgelse uden FPM-genstart har ingen effekt – genindlæs tjenesterne korrekt.- For høje grænser skaber swap-belastning – hellere mere effektive forespørgsler og færre arbejdere.
pm.max_anmodningerSæt ikke på uendeligt – så forbliver lækager i processen for evigt.- Uploads/eksport: POST/upload-begrænsninger (post_max_size, upload_max_filesize) skal tilpasses RAM-kapaciteten.
Kort fortalt: Sådan forhindrer jeg udfald
Jeg kontrollerer først grænseværdien og spidsforbruget, løfter det memory_limit moderat og måler igen. Parallelt slanker jeg plugins, optimerer databasen og fjerner unødvendige udvidelser. Derefter afstemmer jeg OPcache og PHP-FPM, så serveren har nok Buffer for belastningsspidser. Med ren logning og korte belastningstests holder jeg risiciene på et minimum og opdager stille fejl hurtigere. Så forbliver siden stabil, søgemaskiner belønner bedre indlæsningstider – og besøgende bliver.


