web-dev-qa-db-fra.com

Comment limiter l'utilisation de la mémoire dans un processus python

J'exécute Python 2.7 sur une machine Linux avec 16 Go de RAM et un système d'exploitation 64 bits. Un script python que j'ai écrit peut charger trop de données en mémoire, ce qui ralentit le machine au point où je ne peux même plus tuer le processus.

Bien que je puisse limiter la mémoire en appelant:

ulimit -v 12000000

dans mon shell avant d'exécuter le script, je voudrais inclure une option limitante dans le script lui-même. Partout où j'ai regardé, le module resource est cité comme ayant la même puissance que ulimit. Mais en appelant:

import resource
_, hard = resource.getrlimit(resource.RLIMIT_DATA)
resource.setrlimit(resource.RLIMIT_DATA, (12000, hard))

au début de mon script ne fait absolument rien. Même la définition d'une valeur aussi basse que 12000 n'a jamais fait planter le processus. J'ai essayé la même chose avec RLIMIT_STACK, ainsi avec le même résultat. Curieusement, appelant:

import subprocess
subprocess.call('ulimit -v 12000', Shell=True)

ne fait rien aussi bien.

Qu'est-ce que je fais mal? Je n'ai pas trouvé d'exemples d'utilisation réels en ligne.


edit: pour toute personne curieuse, en utilisant subprocess.call ne fonctionne pas car il crée un nouveau processus (surprise, surprise!), qui est indépendant de celui dans lequel le programme python courant s'exécute).

20
Arne

resource.RLIMIT_VMEM est la ressource correspondant à ulimit -v .

RLIMIT_DATAaffecte uniquement brk/sbrk appels système tandis que les nouveaux gestionnaires de mémoire ont tendance à utiliser mmap à la place .

La deuxième chose à noter est que ulimit / setrlimit affecte uniquement le processus actuel et ses futurs enfants.

En ce qui concerne la AttributeError: 'module' object has no attribute 'RLIMIT_VMEM' message: les resource module docs mentionnent cette possibilité:

Ce module ne tente pas de masquer les différences de plate-forme - les symboles non définis pour une plate-forme ne seront pas disponibles à partir de ce module sur cette plate-forme.

Selon la source bashulimit liée ci-dessus, elle utilise RLIMIT_AS si RLIMIT_VMEM n'est pas défini.

13
ivan_pozdeev