Garbage collection does not fully recover from error
L.S., Consider the module definition: // module Infinite where x = 1 : map (+1) x y = 1 : map (+1) y \\ and the following session // Hugs session for: C:\hugs98\lib\Prelude.hs D:\TopFolder\Haskexper\Misc\Infinite.hs Type :? for help Infinite> take 5 x [1,2,3,4,5] Infinite> take 5 x == take 5 y True Infinite> x == y ERROR - Garbage collection fails to reclaim sufficient space Infinite> take 5 x == take 5 y True ERROR - Garbage collection fails to reclaim sufficient space Infinite> \\ The first evaluation of take 5 x == take 5 y causes no problems, but after the stack overflow caused by evaluating x == y the second evaluation of take 5 x == take 5 y returns the correct answer but also an error message. Please let me know (i) whether this should be expected, (ii) if so, why, (iii) if not, how this can be corrected. Regards, Raymond Boute
The first evaluation of take 5 x == take 5 y causes no problems, but after the stack overflow caused by evaluating x == y the second evaluation of take 5 x == take 5 y returns the correct answer but also an error message.
Please let me know (i) whether this should be expected, (ii) if so, why, (iii) if not, how this can be corrected.
i) Yes. ii) Fact 1: Hugs doesn't discard 'CAFs' (i.e., top level definitions of the form x = ...) at the end of evaluation. So CAFs (and the space they consume) linger from one evaluation to the next. This might be useful when teaching Haskell because people can see the effect of lazy evaluation (less reductions taken, more memory consumed). Fact 2: Hugs performs a garbage collection at the end of every execution. (This makes the :gc command kinda superfluous.) This lets Hugs close open file handles and release ForeignObj objects (used in foreign function interface code). Fact 3: Hugs reports an error if a GC fails to recover at least 1000 (I think) cells (a cell is usually 8 bytes). This prevents Hugs from thrashing when memory runs low. What you're seeing is that x==y causes the CAFs to get excessively large and, perhaps as a consequence, x==y fails. Those CAFs are then retained into the 3rd evaluation which is able to run in a very small amount of memory so it can survive with less than 1000 bytes. At the end of the 3rd evaluation, the GC runs and finds there is still less than 1000 bytes so it reports an error. iii) Fixes you can do: - Reload your program - this will cause CAFs to be freed. Fixes we could make to Hugs: - GC at the start of evaluation and refuse to continue if it fails. - Have GC failure abort program execution and clear the CAFs - Have any program failure clear the CAFs - Clear the CAFs at the end of every execution I prefer the first and the last because they make behaviour more consistent. -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
participants (2)
-
Alastair Reid -
Raymond Boute