J'ai un ordinateur portable Debian (Buster) avec 8 Go RAM et 16 Go de swap. J'exécute un très long Cela signifie que mon ordinateur portable est resté allumé pendant les six derniers jours pendant qu'il tourne.
Ce faisant, j'ai régulièrement besoin d'utiliser mon ordinateur portable comme ordinateur portable. Cela ne devrait pas être un problème; la tâche de longue durée est liée aux E/S, travaillant sur des trucs sur un disque dur USB et ne prend pas beaucoup RAM (<200 Mo) ou CPU (<4%).
Le problème est lorsque je reviens à mon ordinateur portable après quelques heures, il sera très lent et peut prendre 30 minutes pour revenir à la normale. C'est tellement mauvais que les crash-moniteurs signalent que leurs applications respectives ont gelé (en particulier les fenêtres de navigateur) et que les choses commencent à se bloquer incorrectement.
En regardant sur le moniteur du système, des 2,5 Go utilisés, environ la moitié sont transférés en swap. J'ai confirmé que c'est le problème en supprimant l'espace de swap (swapoff /dev/sda8
). Si je le laisse sans espace d'échange, il reprend vie presque instantanément même après 24 heures. Avec le swap, c'est pratiquement une brique pour les cinq premières minutes, car il ne reste que six heures. J'ai confirmé que l'utilisation de la mémoire ne dépasse jamais 3 Go même lorsque je suis absent.
J'ai essayé de réduire le swappiness ( voir aussi: Wikipedia ) à des valeurs de 10
et 0
, Mais le problème persiste encore. Il semble qu'après une journée d'inactivité, le noyau pense que l'interface graphique entière n'est plus nécessaire et l'efface de RAM (l'échange sur le disque). La tâche de longue haleine consiste à lire une vaste arborescence de fichiers et la lecture de chaque fichier. Il se peut donc que le noyau soit confus en pensant que la mise en cache serait utile. Mais sur un seul balayage d'un USB HD de 2 To avec ~ 1 milliard de noms de fichiers, un Go supplémentaire RAM = ne va pas beaucoup améliorer les performances. Il s'agit d'un ordinateur portable bon marché avec un disque dur lent. Il ne peut tout simplement pas charger les données dans RAM assez rapidement.
Comment puis-je dire à Linux de n'utiliser l'espace de swap qu'en cas d'urgence? Je ne veux pas courir sans swap. Si quelque chose d'inattendu se produit et que le système d'exploitation a soudainement besoin de quelques Go supplémentaires, je ne veux pas que les tâches soient tuées et je préférerais commencer à utiliser le swap. Mais pour le moment, si je laisse le swap activé, mon ordinateur portable ne peut tout simplement pas être utilisé lorsque j'en ai besoin.
La définition précise d'une "urgence" pourrait faire l'objet d'un débat. Mais pour clarifier ce que je veux dire: Une urgence serait là où le système est laissé sans autre option que d'échanger ou de tuer des processus.
Qu'est-ce qu'une urgence? - Avez-vous vraiment besoin de demander? ... J'espère que vous ne vous retrouverez jamais dans un immeuble en feu !
Il ne m'est pas possible de définir tout ce qui pourrait constituer une urgence dans cette question. Mais par exemple, une urgence peut survenir lorsque le noyau est tellement poussé pour la mémoire qu'il a commencé à tuer les processus avec le OOM Killer . Une urgence N'EST PAS lorsque le noyau pense qu'il peut améliorer les performances en utilisant swap.
Final Edit: J'ai accepté une réponse qui fait exactement ce que j'ai demandé au niveau du système d'exploitation. Les futurs lecteurs devraient également prendre note des réponses proposant des solutions de niveau application.
Avoir un énorme échange de nos jours est souvent une mauvaise idée. Au moment où le système d'exploitation a échangé seulement quelques Go de mémoire à échanger, votre système avait déjà rampé à mort (comme ce que vous avez vu)
Il vaut mieux utiliser zram
avec une petite partition d'échange de sauvegarde . De nombreux systèmes d'exploitation comme ChromeOS , Android et diverses distributions Linux ( Lubunt , Fedora ) ont activé zram par défaut) pendant des années, en particulier pour les systèmes avec moins de RAM. C'est beaucoup plus rapide que d'échanger sur le disque dur et vous pouvez clairement sentir la réactivité du système dans ce cas. Moins ainsi de suite un SSD, mais selon le résultats de référence ici il semble toujours plus rapide même avec l'algorithme lzo par défaut. Vous pouvez passer à lz4 pour des performances encore meilleures avec un peu moins de compression C'est la vitesse de décodage est près de 5 fois plus rapide que lzo basé sur la référence officielle
En fait Windows 1 et macOS utilisent également des techniques similaires compression du fichier d'échange par défaut
Il y a aussi zswap
même si je ne l'ai jamais utilisé. Il vaut probablement la peine d'essayer et de comparer celui qui convient le mieux à vos cas d'utilisation
Après cela, une autre suggestion est de réduire la priorité de ces processus liés aux E/S et éventuellement laisser un terminal en cours d'exécution sur une priorité plus élevée afin que vous puissiez exécuter des commandes dessus tout de suite même lorsque le système est sur une charge élevée
Un correctif consiste à s'assurer que le contrôleur de groupe de mémoire est activé (je pense que c'est par défaut même dans les noyaux semi-récents, sinon vous devrez ajouter cgroup_enable=memory
À la ligne de commande du noyau). Ensuite, vous pouvez exécuter votre tâche intensive d'E/S dans un groupe de contrôle avec une limite de mémoire, ce qui limite également la quantité de cache qu'il peut consommer.
Si vous utilisez systemd, vous pouvez définir +MemoryAccounting=yes
Et MemoryHigh
/MemoryMax
ou MemoryLimit
(dépend de si vous utilisez cgroup v1 ou v2 ) dans l'unité ou une tranche le contenant. S'il s'agit d'une tranche, vous pouvez utiliser systemd-run
Pour exécuter le programme dans la tranche.
Exemple complet d'un de mes systèmes pour exécuter Firefox avec une limite de mémoire. Notez que cela utilise cgroups v2 et est configuré en tant qu'utilisateur, pas root (l'un des avantages de v2 par rapport à v1 est que déléguer cela à non root est sûr, donc systemd le fait).
$ 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 &
J'ai trouvé que pour que l'utilisateur travaille, je devais utiliser une tranche. Le premier système fonctionne simplement en plaçant les options dans le fichier de service (ou en utilisant systemctl set-property
Sur le service).
Voici un exemple de service (en utilisant cgroup v1), notez les deux dernières lignes. Cela fait partie de l'instance système (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 documentation est dans systemd.resource-control(5)
.
Il semble qu'après une journée d'inactivité, le noyau pense que l'interface graphique entière n'est plus nécessaire et l'efface de RAM (l'échange sur le disque).
Le noyau fait la bonne chose ™ le croire. Pourquoi resterait-il inutilisé1 mémoire dans RAM et donc essentiellement gaspiller au lieu de l'utiliser comme cache ou quelque chose?
Je ne pense pas que le noyau Linux permute gratuitement ou par anticipation les pages, donc s'il le fait, cela doit être de stocker autre chose sur la RAM, améliorant ainsi les performances de votre longue tâche, ou du moins avec cet objectif.
Si vous savez quand vous devrez réutiliser votre ordinateur portable à l'avance, vous pouvez utiliser la commande at
(ou crontab
) pour planifier un nettoyage de swap (swapoff -a;swapon -a
).
Comme le nettoyage du swap peut être exagéré, et même déclencher le tueur OOM si, pour une raison quelconque, tout ne tient pas dans la RAM, vous pouvez simplement "décompresser"2 tout ce qui concerne les applications en cours d'exécution que vous souhaitez réactiver.
Une façon de le faire serait d'attacher un débogueur comme gdb
à chacun des processus affectés et de déclencher une génération de vidage de mémoire:
# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit
Comme vous l'avez écrit, votre application longue durée ne réutilise pas les données qu'elle lit après la passe initiale, vous êtes donc dans un cas spécifique où la mise en cache à long terme n'est pas utile. Ensuite, contourner le cache à l'aide d'E/S directes comme suggéré par Will Crawford devrait être une bonne solution de contournement.
Alternativement, vous pouvez simplement vider régulièrement le cache de fichiers en faisant écho à 1
ou 3
à la /proc/sys/vm/drop_caches
pseudo-fichier avant que le système d'exploitation ne pense que c'est une bonne idée d'échanger vos applications et votre environnement GUI.
Voir Comment vider les tampons et le cache sur un système Linux? pour plus de détails.
1Inutilisé dans le sens: plus utilisé activement depuis une période de temps significative, la mémoire étant toujours pertinente pour ses propriétaires.
2Remettez dans RAM pages stockées sur la zone de swap.
Le processus que vous exécutez est-il quelque chose que vous avez créé vous-même?
Si tel est le cas, il peut être utile de modifier votre code pour ouvrir les fichiers à l'aide de O_DIRECT
drapeau, à citer la page de manuel -
Essayez de minimiser les effets de cache des E/S vers et depuis ce fichier. En général, cela dégradera les performances, mais il est utile dans des situations spéciales, comme lorsque les applications effectuent leur propre mise en cache. Les E/S de fichiers sont effectuées directement vers/depuis les tampons de l'espace utilisateur. Le drapeau O_DIRECT fait à lui seul un effort pour transférer les données de manière synchrone, mais ne donne pas les garanties du drapeau O_SYNC que les données et les métadonnées nécessaires sont transférées. Pour garantir des E/S synchrones, O_SYNC doit être utilisé en plus de O_DIRECT. Voir les NOTES ci-dessous pour plus de discussion.
Voici une idée que je n'ai pas essayée moi-même (et je suis désolé de ne pas avoir le temps pour le moment de l'expérimenter).
Supposons que vous créez un petit VM avec seulement 512 Mo de mémoire pour votre processus d'arrière-plan, je ne sais pas si vous souhaitez que cela ait un échange, votre appel et désactivez le swap sur votre système hôte .
Supprimez le swap ou diminuez-le d'environ 20% ( peut varier selon les systèmes) car récemment, les systèmes d'exploitation n'utilisent plus le swap de la même manière qu'il y a quelques années. Cela répond probablement à certaines de vos questions:
certaines des informations Red Hat ci-dessous,
Dans le passé, certains fournisseurs d'applications recommandaient un échange d'une taille égale à la RAM, voire deux fois la RAM. Imaginons maintenant le système susmentionné avec 2 Go de RAM et 2 Go de swap. Une base de données sur le système a été par erreur configurée pour un système avec 5 Go de RAM. Une fois la mémoire physique utilisée , le swap est utilisé. Comme le disque de swap est beaucoup plus lent que la RAM, les performances diminuent et le thrashing se produit. À ce stade, même les connexions au système peuvent devenir impossibles. À mesure que de plus en plus de mémoire est écrite, éventuellement à la fois physique - et la mémoire de swap est complètement épuisée et le tueur OOM entre en action, tuant un ou plusieurs processus.Dans notre cas, beaucoup de swap est disponible, donc le temps de mauvaise performance est long.
et
partie du lien Debian ci-dessus,
Informations et considérations relatives à la quantité de swap à utiliser:
"La quantité recommandée d'espace d'échange est traditionnellement le double de la quantité de mémoire système. Cela a changé avec le temps en une fois et demie de mémoire système, les deux réponses sont des lignes de base décentes mais deviennent de moins en moins des réponses utiles à la question avec le temps. Il existe de nombreuses variables sur votre système et l'utilisation prévue qui détermineront le swap de système disponible que vous voudrez avoir. "
Vous pouvez essayer:
"Le meilleur moyen de désactiver le swap sous linux"
Note personnelle:
Depuis que j'ai 6 Go RAM et dans tous mes OS Linux récemment. Je n'ai jamais vu d'indication d'utilisation de Swap. Je l'ai déterminé que je dois éteignez-le soit pour l'espace (quelques gigaoctets de plus) et parce qu'il a parfois ralenti mon système.