2010-09-22 18 views
10

Estoy acostumbrado a depurar mi código usando ghci. A menudo, sucede algo como esto (no tan obvio, por supuesto):¿Hay alguna manera de limitar la memoria, ghci puede tener?

ghci> let [email protected](_:x) = 0:1:zipWith(+)f x 
ghci> length f 

Entonces, no pasa nada durante algún tiempo, y si no reaccionar lo suficientemente rápido, ghci ha comido quizás 2 GB de RAM, causando mi sistema para congelar Si es demasiado tarde, la única forma de resolver este problema es [ALT] + [IMPRIMIR] + [K].

Mi pregunta: ¿Hay alguna manera fácil de limitar la memoria, que puede ser consumida por ghci, digamos 1 GB? Si el límite se excede, el cálculo debe ser abortado o se debe matar a ghci.

+1

Véase también http://stackoverflow.com/questions/5716216/recovering-from-stack-overflow-or-heap-exhaustion-in-a-haskell -program –

Respuesta

15

Una manera independiente de la plataforma de lograr esto es para suministrar la opción -M como en la opción para el tiempo de ejecución Haskell como esto

ghci +RTS -M1m 

ver the GHC documentation’s page on how to control the RTS (runtime system) para más detalles.

La salida ghci ahora queda como:

>ghci +RTS -M10m 
GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Loading package ffi-1.0 ... linking ... done. 
Prelude> let [email protected](_:x) = 0:1:zipWith(+)f x 
Prelude> length f 
Heap exhausted; 
Current maximum heap size is 10485760 bytes (10 MB); 
use `+RTS -M<size>' to increase it. 
+3

Acabo de crear un alias 'alias ghci = 'ghci + RTS -M500m -RTS'' en' ~/.bashrc' y todo está bien ahora. Muchas gracias. – fuz

+1

Supongo que también podría usar su archivo '.ghci'? http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/ghci-dot-files.html – MatrixFrog

+0

En realidad, esto no se cancela cuando se alcanza el límite, por lo que no es una solución. Además, ghci sigue usando más memoria de la que se indica. Por ejemplo, tengo '4Gb' de RAM, lo configuro en' -M100m'. Me dice que está configurado en '100Mb', lo cual es completamente correcto, pero cuando ejecuto' fib 100000' el programa todavía congela mi máquina.No lo congela por completo como antes, pero la memoria está casi llena y el intercambio se está llenando, causando mucho IO, lo que hace que el sistema no se pueda usar durante dos o más minutos. – Zelphir

2

Correrlo bajo un caparazón con ulimit -m conjunto es una manera bastante fácil. Si desea ejecutar con algún límite de forma regular, puede crear un script de contenedor que haga ulimit antes de ejecutar ghci.

+0

Esto no funciona. Intenté algo como 'ulimit -m 102400' y todavía consume memoria. – fuz

+0

@hobbs @FUZxxl debe usar 'ulimit -v', no' ulimit -m'. El modificador '-m' limita la memoria física, mientras que debe limitar virtual: physical + swap. Yo uso 'ulimit -v $ (((1024 ** 2) * 2))' (zsh) con 4 GiB RAM + 5 GiB swap y no congela el sistema. Esto limita la cantidad de memoria a 2 GiB y se puede poner en '~/.zshrc' o' ~/.bashrc'. – ZyX

+0

Gracias. Encuentro esto menos útil, ya que no puedo cambiar el valor en el caparazón nuevamente después. (Solo hacia abajo ...) – fuz

Cuestiones relacionadas