Obtenha o Python para aumentar o MemoryError em vez de comer todo o meu espaço em disco

7

Se eu executar um programa em Python com vazamento de memória, normalmente esperaria que o programa acabasse morrendo com MemoryError . Mas, em vez disso, o que acontece é que toda a memória virtual é usada até que meu disco fique sem espaço. Estou executando o Mac OS X 10.8 em um MacBook Pro de retina. Meu computador geralmente tem entre 10 GB e 20 GB gratuitos. O Mac OS X é inteligente o suficiente para não morrer completamente quando o disco fica sem espaço (em vez disso, ele me dá uma caixa de diálogo que me permite forçar a saída dos meus programas GUI).

Existe uma maneira de fazer o Python simplesmente morrer quando fica sem memória real ou com uma quantidade razoável de memória virtual? Isto é o que acontece no Linux, tanto quanto eu posso dizer. Eu acho que o Mac OS X é mais generoso do que o Linux com memória virtual (o fato de eu ter um SSD pode ser parte disso; eu não sei o quão inteligente o OS X é com essas coisas). Talvez haja uma maneira de dizer ao kernel do Mac OS X para nunca usar tanta memória virtual que deixe menos de 5 GB livres no disco rígido?

    
por asmeurer 21.11.2012 / 00:56

1 resposta

9

Nível do Python

De acordo com esta postagem , resource.setrlimit () talvez o que você precisa.

Exemplo

#!/usr/bin/python

import resource
import sys
import signal
import time

import os

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

# Use env MY_PY_SET_LIMIT to control limit value
# If MY_PY_SET_LIMIT is not set, RLIMIT_STACK will not change
MY_PY_SET_LIMIT = os.getenv('MY_PY_SET_LIMIT')

if MY_PY_SET_LIMIT != None :
  resource.setrlimit(resource.RLIMIT_STACK, (int(MY_PY_SET_LIMIT), int(MY_PY_SET_LIMIT)))

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

TMP = ""

for i in range(10240):
  TMP += "0123456789"
  print len(TMP)

Nível do sistema

Para Linux , na verdade, é responder várias vezes antes em vários "quadros" de stackexchange e outros sites também. A melhor resposta que encontrei é aqui que contém um exemplo.

A resposta é usar ulimit -v < kByte > . Por exemplo, limitando a vm a 10M:

ulimit -v 10240

No entanto, no OS X , há indicação ( aqui & aqui ) que ulimit talvez ignorar. Esses links são muito antigos. Não tenho certeza se a situação mudou em versões mais recentes do OS X.

Existe este postar para o OS X usar conf conf. Sugerir o uso de uma seção Stack em uma configuração plist

<key>SoftResourceLimits</key>
<dict>
    <key>Stack</key>
    <integer>10000000000</integer>
</dict>

Ou com /etc/launchd.conf

launchd.conf

umask 002
limit stack 67104768 67104768
limit maxproc 3400 4500
limit maxfiles 256 unlimited
setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

PS: de acordo com o homem do Mountain Lion, o launchd.conf (5) por usuário launchd.conf não é compatível

 $HOME/.launchd.conf  Your launchd configuration file (currently unsupported).
    
por 14.12.2012 / 01:08