Recovering from stack overflow or heap exhaustion in a Haskell program

后端 未结 4 2202
情深已故
情深已故 2021-02-10 04:50

I am currently writting a genetic algorithm in Haskell in which my chromosomes are rather complex structures representing executable systems.

In order for me to evaluate

4条回答
  •  北恋
    北恋 (楼主)
    2021-02-10 05:36

    This will be hard to do reliably from inside Haskell -- though under some conditions GHC will raise exceptions for these conditions. (You will need GHC 7).

    import Control.Exception
    

    If you really just want to catch stack overflows, this is possible, as this example shows:

    > handle (\StackOverflow -> return Nothing) $
                  return . Just $! foldr (+) 0 (replicate (2^25) 1) 
    Nothing
    

    Or catching any async exception (including heap exhaustion):

    > handle (\(e :: AsyncException) -> print e >> return Nothing) $
                  return . Just $! foldr (+) 0 (replicate (2^25) 1) 
    stack overflow
    Nothing
    

    However, this is fragile.

    Alternately, with GHC flags you can enforce maximum stack (or heap) size on a GHC-compiled process, causing it to be killed if it exceeds those limits (GHC appears to have no maximum stack limit these days).

    If you compile your Haskell program with GHC (as is recommended), running it as:

    $ ghc -O --make A.hs -rtsopts 
    

    the low heap limit below is enforced:

    $ ./A +RTS -M1M -K1M
    Heap exhausted;
    

    This requires GHC. (Again, you shouldn't be using Hugs for this kind of work). Finally, you should ensure your programs don't use excessive stack in the first place, via profiling in GHC.

提交回复
热议问题