web-dev-qa-db-fra.com

Existe-t-il un moyen de limiter la quantité de mémoire qu'un processus particulier peut utiliser à UNIX?

J'ai besoin de tester un processus de gestion de la mémoire.

  • Je n'ai pas la source, alors j'ai besoin de faire tous les tests du côté du système d'exploitation.
  • Je veux pouvoir dire quelque chose comme limitmemory 400k -p <pid>

Y a-t-il un moyen de le faire à Unix? Tout utilitaire UNIX commun serait excellent.

38
Lazer

ulimit -v, c'est une coquille intégrée, mais cela devrait faire ce que vous voulez.

J'utilise cela dans les scripts init parfois:

ulimit -v 128k
command
ulimit -v unlimited

Il semble toutefois que vous souhaitiez des moyens de manipuler la mémoire allouée maximale lorsque le programme est en cours d'exécution, est-ce correct? Probablement quelque chose comme renice pour manipuler la priorité.

Il n'y a cependant aucun outil de ce type à ma connaissance.

27
polemon

Pour définir la limite lors du démarrage du programme, utilisez ulimit -v 400, comme indiqué par Polemon . Cela définit la limite pour la coque et tous ses descendants, donc dans un script, vous voudrez peut-être utiliser quelque chose comme (ulimit -v 400; myprogram) Pour limiter la portée.

Si vous devez modifier la limite pour un processus en cours d'exécution, il n'y a pas d'utilité pour cela. Vous devez obtenir le processus d'exécution de l'appel système setrlimit. Cela peut souvent être fait avec un débogueur, bien que cela ne fonctionne pas toujours de manière fiable. Voici comment vous pourriez faire cela avec GDB (non testé; 9 est la valeur de RLIMIT_AS sur Linux):

gdb -n -pid $pid -batch -x /dev/stdin <<EOF
call setrlimit(9, {409600, -1})
detach
quit
EOF

Je ne suis pas très sûr à ce sujet, mais vous pouvez également utiliser cgroups pour limiter la tilisation de la mémoire . L'avantage des cgroups est que vous pouvez contrôler les processus déjà en cours d'exécution. Au fait SystemD utilisera des cgroups pour contrôler les services système.

Malheureusement, j'ai un peu expérimenté et ils ne semblent pas très bien travailler sur mon système Fedora 13.

11
Cristian Ciupitu

Sur les systèmes Linux avec noyau> = 2.6.36 et util-linux> = 2.21, vous pouvez utiliser la commande prlimit pour définir une limite de ressources de processus:

prlimit --rss=400000 --pid <pid>
9
Luca Gibelli

Si vous utilisez SystemD, vous pouvez définir des options supplémentaires dans un .service déposer. La liste complète des options que vous pouvez définir est décrite ici .

Vous trouverez ci-dessous un court exemple qui montre comment utiliser cette fonctionnalité de SystemD:

# cat /etc/systemd/system/qbittorrent-nox.service
[Unit]
Description=qbittorrent-nox
Documentation=man:qbittorrent-nox
DefaultDependencies=yes
Requires=media-Kabi.mount
After=media-Kabi.mount network-online.target
Before=multi-user.target
Conflicts=umount.target

[Service]
User=morfik
Group=p2p
Type= simple
RemainAfterExit=no
ExecStart=/usr/bin/qbittorrent-nox
Nice=19
IOSchedulingClass=idle
PrivateNetwork=no
CPUShares=256
MemoryLimit=50M
BlockIOWeight=128
Slice=p2p.slice
StandardError=null
StandardOutput=null

[Install]
WantedBy=multi-user.target

Bien sûr, vous n'avez pas besoin de toutes les options que j'ai utilisées. Si vous voulez simplement limiter l'utilisation de la mémoire, ajoutez MemoryLimit=50M, qui limite à 50mib.

Et c'est le résultat:

# systemctl status qbittorrent-nox.service
● qbittorrent-nox.service - qbittorrent-nox
   Loaded: loaded (/etc/systemd/system/qbittorrent-nox.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2015-05-07 19:25:20 CEST; 1s ago
     Docs: man:qbittorrent-nox
 Main PID: 21712 (qbittorrent-nox)
   Memory: 9.4M (limit: 50.0M)
   CGroup: /p2p.slice/qbittorrent-nox.service
           └─21712 /usr/bin/qbittorrent-nox

May 07 19:25:20 morfikownia systemd[1]: Started qbittorrent-nox.
May 07 19:25:20 morfikownia systemd[1]: Starting qbittorrent-nox...

Jusqu'à présent, cela ne fonctionne que pour les démons/services système, et vous ne pouvez pas limiter, par exemple, un processus Firefox est un utilisateur régulier de cette manière. Mais peut-être Cela changera un jour .

3

Il y a la SETRLIMIT () Fonction , qui permet de configurer les limites d'un processus dans C. Écrivez un programme C pour appeler SETRLIMIT puis pour exécuter la commande que vous souhaitez être limitée. SETRLIMIT ne peut pas modifier les limites des autres processus.

Heureusement, quelqu'un a déjà écrit quelque chose de similaire. Il peut être téléchargé à partir de Freshmeat . J'avais un regard rapide sur le code source et cela semble bien. Utilisez RLIMIT à votre propre discrétion. Notez que RLIMIT ne peut également pas modifier les limites des autres processus.

Edit: Gilles a proposé un joli hack avec GDB: Joindre au processus avec GDB, puis effectuez le processus d'appel de processus SETRLIMIMIT. Cela résoudrait peut-être le problème de limiter un processus déjà en cours d'exécution.

1
nalply

Si vous souhaitez simplement tester et mesurer l'utilisation de la mémoire de votre programme, veuillez regarder heure . Vous pouvez mesurer l'utilisation des ressources de votre programme sous de nombreux aspects, y compris les termes de l'heure de la CPU et de l'utilisation de la mémoire. La commande suivante vous donnera l'utilisation de l'utilisation de la mémoire et de l'heure de la CPU de myProgram:

/usr/bin/time myProgram

(Assurez-vous de donner la voie absolue à la distinguer de la commande de temps intégrée Bash.)

Si vous souhaitez simplement limiter les ressources de votre processus, je vous recommande de créer un utilisateur de test pour cette tâche spécifique. Limitez les ressources de cet utilisateur en fonction de vos besoins et exécutez le processus par l'utilisateur. Il semble que, dans * Nix World, la gestion des ressources basée sur les utilisateurs est beaucoup plus avancée que la gestion des ressources basée sur les processus.

Tu peux vérifier /etc/security/limits.conf Pour limiter les ressources d'un utilisateur. Ou vous pouvez utiliser ulimit après connecté avec l'utilisateur à être limitée.

0
memin