`-M` is too pessimistic with non-moving gc
Summary
The logic for calculating how much heap space a certain amount of live data needs is to pessimistic when using the non-moving gc.
This leads to the maximum heap size set using -M
being prematurely exceeded.
The code that calculates the needed heap space has a case for the compacting gc and the copying gc. When using the non-moving gc the memory requirements should be the same as those of the compacting gc (as done elsewhere), but in this case the case for the copying gc is taken.
Steps to reproduce
Take the following module
module Leak where
import Control.Exception
main = do
let ls = [(1::Int)..]
mapM_ evaluate ls
evaluate ls
Compile it and run it as:
./Leak +RTS -xn -s -A1m -M500M
This will run until the limit set by -M
is reached.
Note the total memory is approx 346MB, when that limit is reached.
Expected behavior
I would expect it to give similar results to running with the compacting gc:
./Leak +RTS -c -s -A1m -M500M
This gives total memory as being 511MB
Environment
- GHC version used: The Glorious Glasgow Haskell Compilation System, version 9.2.0.20210930