Una soluzione è assicurarsi che il controller cgroup di memoria sia abilitato (penso che sia di default anche nei kernel semirecenti, altrimenti dovrai aggiungere cgroup_enable=memory
alla riga di comando del kernel). Quindi puoi eseguire la tua attività intensiva di I/O in un cgroup con un limite di memoria, che limita anche la quantità di cache che può consumare.
Se stai usando systemd, puoi impostare +MemoryAccounting=yes
e MemoryHigh
/MemoryMax
o MemoryLimit
(dipende se stai usando cgroup v1 o v2) nell'unità o in una slice che la contiene. Se è una fetta, puoi usare systemd-run
per eseguire il programma nella slice.
Esempio completo da uno dei miei sistemi per l'esecuzione di Firefox con un limite di memoria. Nota che questo utilizza cgroups v2 ed è impostato come mio utente, non root (uno dei vantaggi di v2 rispetto a v1 è che delegare questo a non-root è sicuro, quindi lo fa systemd).
$ systemctl --user cat mozilla.slice
# /home/anthony/.config/systemd/user/mozilla.slice
[Unit]
Description=Slice for Mozilla apps
Before=slices.target
[Slice]
MemoryAccounting=yes
MemoryHigh=5G
MemoryMax=6G
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/firefox &
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/thunderbird &
Ho scoperto che per far funzionare l'utente dovevo usare una fetta. Il sistema uno funziona semplicemente mettendo le opzioni nel file di servizio (o usando systemctl set-property
sul servizio).
Ecco un servizio di esempio (utilizzando cgroup v1), notare le ultime due righe. Fa parte dell'istanza di sistema (pid=1).
[Unit]
Description=mount S3QL filesystem
Requires=network-online.target
After=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=forking
User=s3ql-user
Group=s3ql-user
LimitNOFILE=20000
ExecStartPre=+/bin/sh -c 'printf "S3QL_CACHE_SIZE=%%i\n" $(stat -c "%%a*%%S*.90/1024" -f /srv/s3ql-cache/ | bc) > /run/local-s3ql-env'
ExecStartPre=/usr/bin/fsck.s3ql --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --log none «REDACTED»
EnvironmentFile=-/run/local-s3ql-env
ExecStart=/usr/bin/mount.s3ql --keep-cache --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --cachesize ${S3QL_CACHE_SIZE} --threads 4
ExecStop=/usr/bin/umount.s3ql /mnt/S3QL/
TimeoutStopSec=2m
MemoryAccounting=yes
MemoryLimit=1G
La documentazione è in systemd.resource-control(5)
.
Sembra che dopo un giorno di inattività il kernel ritenga che l'intera GUI non sia più necessaria e la cancelli dalla RAM (la scambia sul disco).
Il kernel sta facendo The Right Thing™ credendoci. Perché dovrebbe mantenere la memoria inutilizzata nella RAM e quindi essenzialmente sprecarla invece di usarla come cache o qualcosa del genere?
Non penso che il kernel di Linux stia scambiando pagine in modo gratuito o anticipato, quindi se lo fa deve archiviare qualcos'altro sulla RAM, migliorando così le prestazioni della tua attività di lunga durata, o almeno con questo obiettivo.
Se sai in anticipo quando dovrai riutilizzare il tuo laptop, potresti utilizzare at
comando (o crontab
) per pianificare una pulizia dello scambio (swapoff -a;swapon -a
).
Poiché la pulizia dello scambio potrebbe essere eccessiva e persino attivare il killer OOM se per qualche motivo non tutto si adatta alla RAM, potresti semplicemente "annullare lo scambio" di tutto ciò che riguarda le applicazioni in esecuzione che desideri ripristinare.
Un modo per farlo sarebbe collegare un debugger come gdb
a ciascuno dei processi interessati e attivare una generazione di core dump:
# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit
Come hai scritto, la tua applicazione a esecuzione prolungata non riutilizza i dati che legge dopo il passaggio iniziale, quindi ti trovi in un caso specifico in cui la memorizzazione nella cache a lungo termine non è utile. Quindi bypassare la cache utilizzando l'I/O diretto come suggerito da Will Crawford dovrebbe essere una buona soluzione.
In alternativa, potresti semplicemente svuotare regolarmente la cache del file echeggiando 1
o 3
al /proc/sys/vm/drop_caches
pseudo-file prima che il sistema operativo ritenga che sia una buona idea sostituire le applicazioni e l'ambiente della GUI.
Vedi Come si svuotano i buffer e la cache su un sistema Linux? per i dettagli.
Inutilizzato nel senso:non più utilizzato attivamente da un periodo di tempo significativo, la memoria è ancora rilevante per i suoi proprietari.
Rimette in RAM le pagine memorizzate nell'area di scambio.
Avere uno scambio così grande al giorno d'oggi è spesso una cattiva idea. Quando il sistema operativo ha scambiato solo pochi GB di memoria per lo scambio, il tuo sistema era già andato a morte (come quello che hai visto)
È meglio usare zram
con una piccola partizione di swap di backup . Molti sistemi operativi come ChromeOS, Android e varie distribuzioni Linux (Lubuntu, Fedora) hanno abilitato zram per impostazione predefinita per anni, soprattutto per i sistemi con meno RAM. È molto più veloce piuttosto che scambiare su HDD e in questo caso puoi sentire chiaramente la reattività del sistema. Meno su un SSD, ma secondo i risultati del benchmark qui sembra ancora più veloce anche con l'algoritmo lzo predefinito. Puoi passare a lz4 per prestazioni ancora migliori con un rapporto di compressione leggermente inferiore. La sua velocità di decodifica è quasi 5 volte superiore rispetto a lzo in base al benchmark ufficiale
Infatti Windows 10 e macOS utilizzano anche tecniche di compressione dei file di paging simili per impostazione predefinita
C'è anche zswap
anche se non l'ho mai usato. Probabilmente vale la pena provare e confrontare qual è il migliore per i tuoi casi d'uso
Successivamente, un altro suggerimento è di ridurre la priorità di quei processi legati all'IO e possibilmente lasciare un terminale in esecuzione con una priorità più alta in modo da poter eseguire comandi su di esso immediatamente anche quando il sistema è sotto carico elevato
Ulteriori letture
- Arch Linux - Miglioramento delle prestazioni - Zram o zswap
- Abilita ZSwap per aumentare le prestazioni
- Abilita zRAM per una migliore gestione della memoria e meno swapping
- Stai esaurendo la RAM in Ubuntu? Abilita ZRAM
- Differenza tra ZRAM e ZSWAP
- zram vs zswap vs zcache Guida definitiva:quando usare quale
- Linux, SSD e scambio
- https://wiki.debian.org/ZRam
- https://www.kernel.org/doc/Documentation/blockdev/zram.txt
- https://wiki.gentoo.org/wiki/Zram