Recovering from stack overflow or heap exhaustion in a Haskell program

后端 未结 4 2201
情深已故
情深已故 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:20

    A thought on your genetic algorithm: Part of the fitness of your chromosomes is that they do not consume too many computational resources. The question you asked defines "too many resources" as crashing the runtime system. This is a rather arbitrary and somewhat random measure.

    Knowing that it will add to the complexity of your evolve function, I still would suggest that this function be made aware of the computational resources that a chromosome consumes. This allows you to fine tune when it has "eaten" too much and dies prematurely of "starvation". It might also allow you to adjust your penalty based on how rapidly the chromosome went exponential with the idea that a chromosome that is just barely exponential is more fit then one with an extremely high branching factor.

    0 讨论(0)
  • 2021-02-10 05:25
    It seems to me like the best solution would be to tell the program: 
    "Hey, try doing this, but if you fail don't worry. I know how to handle it"
    

    In most languages that would be a try/catch block. I'm not sure what the equivalent is in haskell, or even if some equivalent exists. Furthermore, I doubt that a try/catch construct could effectively trap/handle a stack overflow condition.

    But would it be possible to apply some reasonable constraints to prevent the overflow from occurring? For instance, perhaps you could set some upper-bound on the size of a system, and monitor how each system approaches the boundary from one iteration to the next. Then you could enforce a rule like "if on a single evolution a system either exceeded its upper-bound or consumed more than 50% of the space remaining between its previous allocation and its upper-bound, that system is terminated and suffers a score penalty".

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2021-02-10 05:39

    I think a general solution here is to provide a way to measure computation time, and kill it if it takes too much time. You can simply add counter to your evaluation function if it's recursive and if it drops to zero you return an error value - for example Nothing, otherwise it's Just result.

    This approach can be implemented in other ways than explicit count parameter, for example by putting this counter into monad used by evaluation (if your code is monadic) or, impurely, by running computation in separate thread that will be killed on timeout.

    I would rather use any pure solution, since it would be more reliable.

    0 讨论(0)
提交回复
热议问题