Leggere "free: 180MB" su un server da 8 GB fa spaventare qualcuno ogni giorno, e quasi sempre va tutto bene. Linux usa la memoria avanzata come cache del disco e la restituisce nell'istante in cui qualcosa la richiede. Il numero da leggere è available, non free.
free -h
# total used free shared buff/cache available
# Mem: 7.8Gi 2.1Gi 180Mi 120Mi 5.5Gi 5.3Gi
5,3 Gi in available vuol dire che ci sono 5,3 Gi da prendere. La cache non è memoria persa; è memoria che fa qualcosa di utile finché non serve.
Lo swap è il numero che conta
Che lo swap sia OCCUPATO non è il problema. Che ci si stia attivamente scrivendo e leggendo sì: la macchina sposta pagine sul disco per far spazio, e il disco è migliaia di volte più lento della memoria. Tutto è lento e nell'applicazione non c'è nulla che lo spieghi.
vmstat 2 5
# watch the si and so columns - sustained non-zero is thrashing
Trovi che cosa la tiene
ps aux --sort=-%mem | head -10
smem -rs uss 2>/dev/null | head -10
uss è la memoria che un processo libererebbe davvero se terminasse, ed è la cifra onesta. rss conta due volte le librerie condivise e fa sembrare enorme ogni worker PHP.
La risposta di sempre
- Troppi worker PHP. Un pm.max_children preso da una guida invece che calcolato dalla sua RAM. Divida la memoria disponibile per il worker medio, e stia largo.
- Un innodb_buffer_pool_size troppo grande. Un database a cui si chiede di tenere in cache più di quanto la macchina possieda.
- Una perdita in un worker di lunga durata. Lo riavvii periodicamente; php-fpm lo fa con pm.max_requests.
Un po' di swap è sano: consente al kernel di spostare da parte le pagine davvero inattive. Un server con lo swap disattivato del tutto non ha cuscinetto e viene ucciso di netto appena la memoria scarseggia.