PrestaShop Memory Limit Superato: Cause e Soluzioni
Comprendere memory_limit di PHP
La direttiva memory_limit di PHP controlla quanta RAM un singolo processo PHP può consumare prima che il motore lo termini con un errore fatale. Quando vedi il messaggio "Allowed memory size of X bytes exhausted" in PrestaShop, significa che una specifica richiesta PHP ha tentato di utilizzare più memoria di quanto il limite configurato consenta.
Ogni caricamento di pagina in PrestaShop esegue codice PHP che carica il framework, si connette al database, elabora i dati, renderizza i template e invia l'HTML al browser. Ognuno di questi passaggi consuma memoria. Il memory_limit agisce come una rete di sicurezza: impedisce a un singolo processo fuori controllo di consumare tutta la RAM disponibile del server, il che causerebbe il crash di altri processi e potenzialmente l'intera infrastruttura.
Il memory_limit predefinito in PHP è tipicamente 128M (128 megabyte). PrestaShop raccomanda ufficialmente almeno 256M, e molti negozi richiedono 512M o più a seconda della dimensione del catalogo, dei moduli installati e del traffico. Comprendere cosa guida il consumo di memoria ti aiuta a determinare il valore giusto per il tuo negozio piuttosto che aumentare il limite alla cieca.
Come Verificare il Tuo Memory Limit Attuale
Esistono diversi modi per verificare quale memory limit sta attualmente utilizzando la tua installazione PrestaShop.
Dal Back Office di PrestaShop
Naviga in Parametri Avanzati > Informazioni. Questa pagina mostra la configurazione PHP del tuo server, incluso il valore corrente di memory_limit. PrestaShop mostrerà anche avvisi se il valore è inferiore al minimo raccomandato.
Usando phpinfo()
Crea un file temporaneo chiamato info.php nella directory principale di PrestaShop con questo contenuto:
<?php phpinfo(); ?>Accedici tramite il browser all'indirizzo tuodominio.com/info.php. Cerca nella pagina "memory_limit" per vedere sia il Valore Locale (quello effettivamente attivo) sia il Valore Master (quello impostato in php.ini). Il valore locale può differire dal valore master se un .htaccess, .user.ini o l'applicazione stessa lo sovrascrive.
Importante: Elimina questo file immediatamente dopo il controllo. Una pagina phpinfo() espone la configurazione dettagliata del server che gli attaccanti possono sfruttare.
Via Riga di Comando
Se hai accesso SSH, esegui:
php -i | grep memory_limitNota che la configurazione PHP da CLI potrebbe differire dalla configurazione del server web. Per controllare il valore web-facing, usa il metodo phpinfo() o il back office di PrestaShop.
Cause Comuni degli Errori di Memory Limit
Importazioni di Prodotti Massive
L'importazione di prodotti tramite CSV è una delle operazioni più intensive in termini di memoria in PrestaShop. Ogni riga nel file di importazione viene caricata in memoria, elaborata, validata e inserita nel database. Un file CSV con 10.000 prodotti, ognuno con multiple combinazioni, immagini e descrizioni, può facilmente richiedere 512MB o più di memoria.
Lo strumento di importazione di PrestaShop elabora i prodotti in batch, ma la dimensione del batch e la quantità di dati per prodotto determinano il footprint di memoria totale. Campi di testo grandi (descrizioni con HTML), molte colonne e file codificati in UTF-8 con caratteri speciali aumentano tutti l'utilizzo di memoria per riga.
Per ridurre il consumo di memoria durante le importazioni:
- Dividi i file CSV grandi in parti più piccole (1.000-2.000 righe ciascuna)
- Importa prima i prodotti senza immagini, poi importa le immagini separatamente
- Disabilita i moduli non essenziali durante l'importazione (statistiche, indicizzazione ricerca)
- Usa l'importazione da riga di comando se disponibile, che evita i limiti di timeout del server web
Prodotti con Molte Combinazioni
I prodotti con molti attributi (taglia, colore, materiale) generano combinazioni in modo esponenziale. Un prodotto con 5 taglie, 10 colori e 3 materiali crea 150 combinazioni. Ogni combinazione è un record separato nel database con il proprio prezzo, riferimento, stock e associazioni di immagini. Quando PrestaShop carica una pagina prodotto per la modifica nel back office, carica tutte le combinazioni in memoria contemporaneamente.
I prodotti con 500+ combinazioni sono un punto critico noto. Con 1.000+ combinazioni, raggiungerai quasi certamente i limiti di memoria con la configurazione predefinita. Le soluzioni includono:
- Aumentare
memory_limita 512M o 1G per il back office - Ristrutturare i prodotti per ridurre il numero di combinazioni (prodotti separati invece di mega-combinazioni)
- Utilizzare moduli che gestiscono le combinazioni in modo più efficiente tramite paginazione
Moduli Sovraccaricati o Mal Codificati
I moduli di terze parti sono una fonte frequente di problemi di memoria. I problemi comuni includono:
- Caricamento di intere tabelle del database in array PHP: Un modulo che esegue
SELECT * FROM ps_orderssenza una clausola LIMIT carica in memoria ogni ordine mai effettuato. Per un negozio con 100.000 ordini, questo può consumare centinaia di megabyte. - Perdite di memoria nei cicli: Moduli che elaborano elementi in un ciclo ma accumulano oggetti senza liberarli. Il garbage collector di PHP gestisce i casi semplici, ma i riferimenti circolari e i riferimenti memorizzati possono impedire la pulizia.
- Logging eccessivo: Logging di debug che scrive array o oggetti di grandi dimensioni nei file di log, usando
var_export()oprint_r()su oggetti PrestaShop complessi, può consumare enormi quantità di memoria. - Elaborazione immagini non ottimizzata: Moduli che ridimensionano o applicano watermark alle immagini usando GD o ImageMagick caricano l'intera immagine non compressa in memoria. Un'immagine 5000x5000 pixel a 24 bit di profondità colore richiede approssimativamente 75MB di RAM solo per i dati dei pixel.
Per identificare quale modulo sta causando problemi di memoria, controlla attentamente il messaggio di errore. Di solito include un percorso file che punta al modulo responsabile. Puoi anche abilitare la modalità debug di PrestaShop per ottenere stack trace più dettagliati.
Cataloghi Grandi e Query Complesse
I negozi con decine di migliaia di prodotti, molte categorie e strutture di attributi complesse esercitano più pressione sulla memoria durante il normale funzionamento. Le pagine di categoria con la navigazione a strati (ricerca a facette) sono particolarmente impegnative perché il motore dei filtri deve calcolare i valori degli attributi disponibili su migliaia di prodotti.
L'elenco prodotti del back office, l'elenco ordini e l'elenco clienti caricano tutti dati in memoria per la visualizzazione. Con dataset molto grandi, anche la vista elenco di base può raggiungere i limiti di memoria, specialmente quando i moduli aggiungono colonne o calcoli extra a questi elenchi.
Compilazione dei Template Smarty
PrestaShop utilizza il motore di template Smarty, che compila i template in file PHP per un rendering più veloce. Il processo di compilazione stesso consuma memoria, e i template complessi con molti include, cicli e blocchi condizionali richiedono più memoria per la compilazione. Dopo la prima compilazione vengono utilizzate le versioni in cache, quindi questo è principalmente un problema quando la cache viene svuotata o durante lo sviluppo.
Come Aumentare il Memory Limit
Metodo 1: php.ini
Il metodo più affidabile è modificare direttamente il file di configurazione PHP. La posizione dipende dalla tua configurazione:
- Debian/Ubuntu:
/etc/php/8.x/fpm/php.ini(PHP-FPM) o/etc/php/8.x/apache2/php.ini(mod_php) - CentOS/RHEL:
/etc/php.inio/etc/php.d/ - cPanel: MultiPHP INI Editor in WHM o cPanel
Trova la riga memory_limit e modificala:
memory_limit = 512MDopo il salvataggio, riavvia PHP-FPM o Apache:
# PHP-FPM
sudo systemctl restart php8.2-fpm
# Apache con mod_php
sudo systemctl restart apache2Metodo 2: .htaccess (Solo Apache con mod_php)
Aggiungi questa riga al file .htaccess nella directory principale di PrestaShop:
php_value memory_limit 512MQuesto metodo funziona solo con Apache che esegue mod_php. Se usi PHP-FPM (che è più comune nelle configurazioni moderne), questa direttiva viene silenziosamente ignorata o può causare un errore 500. Per verificare quale handler PHP stai usando, guarda la riga Server API nell'output di phpinfo().
Metodo 3: .user.ini (PHP-FPM)
Crea o modifica un file chiamato .user.ini nella directory principale di PrestaShop:
memory_limit = 512MPHP-FPM legge i file .user.ini dalla document root. Nota che le modifiche hanno effetto dopo il periodo user_ini.cache_ttl (predefinito 300 secondi / 5 minuti), quindi potresti dover attendere o riavviare PHP-FPM affinché la modifica abbia effetto immediatamente.
Metodo 4: All'Interno del Codice di PrestaShop
PrestaShop imposta il proprio memory limit nel file config/defines.inc.php. Cerca una riga come:
@ini_set('memory_limit', '256M');Puoi aumentare questo valore direttamente nel codice. Tuttavia, questo approccio ha una limitazione: la funzione ini_set() può solo aumentare il memory limit fino al valore impostato in php.ini. Se php.ini imposta memory_limit = 128M e il tuo codice tenta di impostarlo a 512M, il limite effettivo rimarrà 128M (a meno che il valore master non consenta le sovrascritture, il che dipende dalla classificazione PHP_INI_ALL vs PHP_INI_SYSTEM).
Metodo 5: Configurazione Per-Pool (PHP-FPM)
Se gestisci il tuo server, puoi impostare i limiti di memoria per pool PHP-FPM. Modifica il file di configurazione del pool (es. /etc/php/8.2/fpm/pool.d/www.conf) e aggiungi:
php_admin_value[memory_limit] = 512MUsando php_admin_value questa impostazione diventa immutabile — non può essere sovrascritta da .user.ini o ini_set(). Questo è utile per applicare limiti in ambienti multi-tenant.
Memoria Per-Processo vs Memoria Condivisa
È importante capire che memory_limit si applica a ogni singolo processo PHP, non a PHP nel suo complesso. Se imposti memory_limit = 512M e il tuo server esegue 20 processi PHP concorrenti, il consumo massimo teorico di memoria da parte di PHP è 10GB (20 x 512MB).
Ecco perché aumentare ciecamente il memory limit può causare problemi. Su un server con 4GB di RAM, impostare memory_limit = 1G con 10 worker PHP-FPM significa che PHP da solo potrebbe tentare di usare 10GB, causando un pesante swapping del sistema o attivando il Linux OOM killer, che termina forzatamente i processi per liberare memoria.
L'approccio corretto è bilanciare il memory limit con il numero di worker PHP:
- RAM disponibile per PHP = RAM totale - overhead SO - memoria MySQL - memoria server web - altri servizi
- Worker PHP massimi = RAM disponibile per PHP / memory_limit
Ad esempio, su un VPS da 4GB: 4GB totali - 0,5GB SO - 1GB MySQL - 0,25GB Nginx = 2,25GB per PHP. Con memory_limit = 256M, puoi eseguire in sicurezza 8-9 worker PHP-FPM. Con memory_limit = 512M, puoi eseguire solo 4 worker, il che significa che meno richieste concorrenti possono essere servite.
Configura il pool PHP-FPM di conseguenza:
pm = dynamic
pm.max_children = 8
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5Diagnosticare Perdite di Memoria e Uso Eccessivo
Se aumentare il memory limit ritarda solo l'errore anziché risolverlo, probabilmente hai una perdita di memoria o un processo inefficiente. Ecco come diagnosticare la causa principale.
Abilita la Modalità Debug di PrestaShop
Modifica config/defines.inc.php e imposta:
define('_PS_MODE_DEV_', true);Questo abilita la segnalazione dettagliata degli errori, incluso il file esatto e il numero di riga in cui il memory limit è stato superato. Lo stack trace mostra la catena di chiamate di funzione che ha portato all'errore, aiutandoti a identificare il modulo o la funzione core responsabile.
Monitora l'Uso della Memoria nel Codice
Puoi aggiungere il monitoraggio della memoria a sezioni specifiche del codice per individuare dove si verificano i picchi di memoria:
error_log('Memoria prima dell\'operazione: ' . memory_get_usage(true) / 1024 / 1024 . ' MB');
// ... operazione ...
error_log('Memoria dopo l\'operazione: ' . memory_get_usage(true) / 1024 / 1024 . ' MB');
error_log('Picco di memoria: ' . memory_get_peak_usage(true) / 1024 / 1024 . ' MB');La funzione memory_get_usage(true) restituisce la quantità effettiva di memoria allocata dal SO a PHP, mentre memory_get_peak_usage(true) restituisce la quantità massima allocata in qualsiasi punto durante la richiesta.
Usa il Profiling di Xdebug
Il profiler di Xdebug genera report dettagliati delle chiamate di funzione, del tempo di esecuzione e del consumo di memoria. Abilitalo temporaneamente nella configurazione PHP:
xdebug.mode = profile
xdebug.output_dir = /tmp/xdebugApri i file cachegrind generati in uno strumento come KCacheGrind o Webgrind per visualizzare quali funzioni consumano più memoria. Questo è l'approccio diagnostico più approfondito ma dovrebbe essere utilizzato solo su server di sviluppo a causa del significativo overhead sulle prestazioni.
Controlla le Query Lente e MySQL
A volte quello che sembra essere un problema di memoria PHP è in realtà un problema MySQL. Una query lenta che restituisce milioni di righe causerà l'allocazione di memoria PHP per l'intero set di risultati. Controlla il log delle query lente di MySQL:
sudo tail -100 /var/log/mysql/slow-query.logSe vedi query con set di risultati grandi, aggiungi clausole LIMIT appropriate o implementa la paginazione nel modulo responsabile.
Memoria OPcache
OPcache è un'estensione PHP che memorizza nella cache il bytecode PHP compilato in memoria condivisa, eliminando la necessità di analizzare e compilare i file PHP ad ogni richiesta. OPcache ha la propria allocazione di memoria, separata da memory_limit.
La memoria OPcache predefinita (opcache.memory_consumption) è 128MB. PrestaShop con diversi moduli installati può facilmente superare questo valore. Quando OPcache esaurisce la memoria, inizia a espellere le voci in cache e ricompilare i file ad ogni richiesta, causando un significativo degrado delle prestazioni.
Controlla lo stato di OPcache dalla riga di comando:
php -r "print_r(opcache_get_status());"Oppure guarda la sezione opcache nell'output di phpinfo(). Valori chiave da monitorare:
- opcache.memory_consumption: Memoria totale allocata per OPcache (aumenta a 256M per PrestaShop)
- opcache.max_accelerated_files: Numero massimo di file che OPcache può memorizzare in cache (aumenta a 20000 per PrestaShop)
- Memoria usata vs Memoria libera: Se la memoria libera è vicina allo zero, aumenta
memory_consumption - Cache hit rate: Dovrebbe essere superiore al 99%. Sotto il 95% indica pressione sulla memoria o invalidazione frequente della cache
Configurazione OPcache raccomandata per PrestaShop:
opcache.enable = 1
opcache.memory_consumption = 256
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 1
opcache.revalidate_freq = 0
opcache.interned_strings_buffer = 16Nota che la memoria OPcache è condivisa tra tutti i processi PHP, a differenza di memory_limit che è per singolo processo. Aumentare la memoria OPcache non si moltiplica per il numero di worker.
Configurazione Memoria MySQL
MySQL ha la propria configurazione di memoria che influenza indirettamente le prestazioni di PrestaShop e può contribuire alla pressione complessiva sulla memoria del server. Le principali impostazioni di memoria MySQL includono:
- innodb_buffer_pool_size: Il buffer di memoria principale per le tabelle InnoDB. Imposta al 50-70% della RAM disponibile su un server database dedicato, o al 25-50% su un server condiviso che esegue sia PHP che MySQL. Questa è la singola impostazione di prestazioni MySQL più importante.
- sort_buffer_size e join_buffer_size: Buffer per connessione per ordinamento e join. Mantienili ai valori predefiniti a meno che tu non abbia query lente specifiche che beneficerebbero di buffer più grandi. Impostarli troppo alti spreca memoria perché vengono allocati per connessione.
- query_cache_size: Deprecato in MySQL 8.0 e rimosso completamente. Se sei ancora su MySQL 5.7, una piccola cache query (64M) può aiutare, ma cache grandi causano contesa e riducono le prestazioni.
Se MySQL consuma troppa memoria, ne rimane meno per PHP, potenzialmente costringendoti a ridurre i worker PHP-FPM o il memory limit. Usa mysqladmin status o SHOW GLOBAL STATUS per monitorare il consumo di memoria di MySQL.
Quando Aggiornare il Tuo Hosting
A volte aumentare il memory limit e ottimizzare il codice non è sufficiente. Ecco i segnali che indicano la necessità di un server più potente:
- Stai costantemente raggiungendo il memory limit massimo: Se i tuoi processi utilizzano regolarmente il 90%+ della memoria allocata, anche dopo l'ottimizzazione, hai bisogno di più RAM.
- Il server fa swap frequentemente: Controlla con
free -hovmstat 1. Se l'utilizzo dello swap è costantemente alto, non hai abbastanza RAM fisica. - Ridurre i worker PHP sta penalizzando le prestazioni: Se hai dovuto ridurre i worker PHP-FPM a 3-4 per accomodare il memory limit, il tuo sito non può gestire efficacemente i visitatori concorrenti.
- Il tuo catalogo continua a crescere: Un negozio che funzionava bene con 1.000 prodotti potrebbe avere difficoltà con 10.000. Le esigenze di memoria scalano con la dimensione del catalogo, specialmente per l'indicizzazione della ricerca, l'elenco delle categorie e le operazioni del back office.
- Hai bisogno di memory_limit superiore a 1G: Se un singolo processo PHP necessita di più di 1GB di memoria per operazioni normali (non importazioni), qualcosa è fondamentalmente sbagliato nel tuo codice o nella capacità del tuo hosting. Investiga la causa principale prima di continuare ad aumentare il limite.
Quando aggiorni, dai priorità a più RAM rispetto a più core CPU per PrestaShop. Un server con 8GB di RAM e 2 core servirà PrestaShop meglio di uno con 4GB di RAM e 4 core. Considera anche la separazione di MySQL su un proprio server o l'uso di un servizio di database gestito, che libera completamente la RAM del server applicativo per PHP.
Riferimento Rapido: Impostazioni Raccomandate per Dimensione del Negozio
Le seguenti raccomandazioni servono come punti di partenza. Monitora il tuo utilizzo effettivo e regolati di conseguenza.
- Negozio piccolo (meno di 1.000 prodotti, pochi moduli):
memory_limit = 256M, 2GB RAM, 4-6 worker PHP - Negozio medio (1.000-10.000 prodotti, 20+ moduli):
memory_limit = 512M, 4GB RAM, 6-8 worker PHP - Negozio grande (10.000+ prodotti, molte combinazioni):
memory_limit = 512M-1G, 8GB+ RAM, 8-16 worker PHP, server database separato - Durante le importazioni: Aumenta temporaneamente a
1Go2G, poi ripristina il valore normale
Ricorda che il memory limit è un tetto di sicurezza, non un obiettivo. Un negozio PrestaShop ben ottimizzato dovrebbe raramente utilizzare più di 128-256MB per richiesta durante i normali caricamenti di pagina. Se le operazioni normali necessitano costantemente di 512MB o più, investiga e correggi la causa sottostante piuttosto che continuare ad aumentare il limite.
Questa risposta ti è stata utile?
Hai ancora domande?
Can't find what you're looking for? Send us your question and we'll get back to you quickly.