2010-09-22 5 views
10

Sono abituato a eseguire il debug del mio codice usando ghci. Spesso, qualcosa di simile accade (non così ovvio, ovviamente):C'è un modo per limitare la memoria, ghci può avere?

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

Poi, non succede nulla per un po 'di tempo, e se non reagisco abbastanza velocemente, ghci ha mangiato forse 2 GB di RAM, causando il mio sistema per congelare. Se è troppo tardi, l'unico modo per risolvere questo problema è [ALT] + [STAMPA] + [K].

La mia domanda: C'è un modo semplice per limitare la memoria, che può essere consumata da ghci, diciamo 1 GB? Se il limite è superato, il calcolo dovrebbe essere interrotto o ghci dovrebbe essere ucciso.

+1

Vedi anche http://stackoverflow.com/questions/5716216/recovering-from-stack-overflow-or-heap-exhaustion-in-a-haskell -programma –

risposta

15

Un modo indipendente dalla piattaforma per raggiungere questo obiettivo è quello di fornire l'opzione -M come in opzione al runtime Haskell come questo

ghci +RTS -M1m 

vedere the GHC documentation’s page on how to control the RTS (runtime system) per i dettagli.

Il ghci uscita sembra ormai come:

>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

Ho appena creato un alias 'alias ghci = 'ghci + RTS -M500m -RTS'' in' ~/.bashrc' e tutto è a posto ora. Grazie mille. – fuz

+1

Suppongo che potresti anche usare il tuo file '.ghci'? http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/ghci-dot-files.html – MatrixFrog

+0

In realtà questo non si interrompe quando viene raggiunto il limite, quindi non è una soluzione. Inoltre ghci continua a utilizzare più memoria di quella dichiarata. Per esempio ho '4Gb' di RAM, l'ho impostato a' -M100m'. Mi dice che è impostato a '100Mb', che va benissimo, ma quando eseguo un' fib 100000' il programma ancora alomst congela la mia macchina.Non lo congela completamente come prima, ma la memoria è quasi piena e lo swap viene riempito, causando un sacco di IO, rendendo il sistema inutilizzabile per due o più minuti. – Zelphir

2

L'esecuzione sotto un guscio con ulimit -m set è un modo abbastanza semplice. Se si desidera eseguire con un certo limite su base regolare, è possibile creare uno script wrapper che faccia ulimit prima di eseguire ghci.

+0

Questo non funziona. Ho provato qualcosa come 'ulimit -m 102400' e continua a consumare memoria. – fuz

+0

@hobbs @FUZxxl dovresti usare 'ulimit -v', non' ulimit -m'. L'opzione '-m' limita la memoria fisica, mentre è necessario limitare virtual: physical + swap. Io uso 'ulimit -v $ (((1024 ** 2) * 2))' (zsh) con 4 GiB RAM + 5 GiB swap e non congela il sistema. Questo limita la quantità di memoria a 2 GiB e può essere inserita in ~ ~/.zshrc' o '~/.bashrc'. – ZyX

+0

Grazie. Trovo questo meno utile, in quanto non posso cambiare il valore nella shell di nuovo in seguito. (Solo in basso ...) – fuz