2010-02-22 7 views
45

J'écris parfois des programmes Python qui sont très difficiles à déterminer combien de mémoire il utilisera avant l'exécution. En tant que tel, j'appelle parfois un programme Python qui essaie d'allouer des quantités massives de RAM provoquant l'échange lourd du noyau et dégrader les performances des autres processus en cours d'exécution. Pour cette raison, je souhaite limiter la quantité de mémoire qu'un tas Python peut croître. Lorsque la limite est atteinte, le programme peut simplement tomber en panne. Quelle est la meilleure façon de faire cela? Si cela est important, beaucoup de code est écrit en Cython, donc cela devrait prendre en compte la mémoire qui y est allouée. Je ne suis pas marié à une pure solution Python (elle n'a pas besoin d'être portable), donc tout ce qui fonctionne sur Linux est bien.Comment limiter la taille du tas?

+4

Je suis confus à propos de cette question. Il semble inclure une réponse, mais n'indique pas ce qui ne va pas. – amcnabb

+0

On dirait qu'il a copié le code de la réponse acceptée dans sa question. Vraisemblablement c'est la solution? – fantabolous

+0

@amcnabb J'ai supprimé la réponse à la question – Djizeus

Répondre

45

Découvrez resource.setrlimit(). Cela ne fonctionne que sur les systèmes Unix, mais il semble que ce soit ce que vous recherchez, car vous pouvez choisir une taille de segment maximale pour votre processus et les enfants de votre processus avec le paramètre resource.RLIMIT_DATA.

EDIT: Ajout d'un exemple:

import resource 

rsrc = resource.RLIMIT_DATA 
soft, hard = resource.getrlimit(rsrc) 
print 'Soft limit starts as :', soft 

resource.setrlimit(rsrc, (1024, hard)) #limit to one kilobyte 

soft, hard = resource.getrlimit(rsrc) 
print 'Soft limit changed to :', soft 

Je ne suis pas sûr de ce que votre cas d'utilisation est exactement, mais il est possible que vous devez placer une limite sur la taille de la pile à la place avec resouce.RLIMIT_STACK. Passer cette limite enverra un signal SIGSEGV à votre processus, et pour le gérer, vous devrez utiliser une pile de signaux alternative comme décrit dans le setrlimit Linux manpage. Je ne suis pas sûr si sigaltstack est implémenté en python, donc, cela pourrait s'avérer difficile si vous voulez récupérer d'aller au-delà de cette limite.

+3

Pouvez-vous donner un exemple? J'ai essayé de définir des limites de ressources, mais j'étais toujours capable d'allouer une liste de gigaoctets. Le module de ressources "se sent bien", mais je ne peux pas le faire fonctionner sur Linux. – carl

+0

J'ai ajouté mon test à la question. Ma compréhension est que le programme Python devrait quitter une fois la limite est atteinte. – carl

+2

Aussi, je me fiche de ce qui se passe si la limite est atteinte - le programme peut tomber en panne, se bloquer, ou autre, aussi longtemps qu'il n'alloue pas plus de mémoire. – carl

0

Jetez un oeil à ulimit. Il permet de définir des quotas de ressources. Peut nécessiter des paramètres de noyau appropriés.

+0

Lorsque vous utilisez PAM de toute façon, '/ etc/security/limits.conf' est le meilleur endroit pour fixer des limites. 'ulimit' est seulement une fonction shell Bash. –

+0

ulimit utilise les mêmes appels système que le module de ressources Python – Willem

Questions connexes