
I have not been following the details of this, I'm afraid, but I notice
Am Samstag 17 April 2010 14:41:28 schrieb Simon Peyton-Jones: this:
forever' m = do _ <- m forever' m
When I define that version of forever, the space leak goes away.
What was the old version of forever that led to the leak?
Control.Monad.forever forever :: Monad m => m a -> m b forever m = m >> forever m However, that isn't the problem. In my tests, both variants of forever exhibit the same behaviour, what makes it leak or not is the optimisation level.
If you can boil down the leak to a simple test case, do submit a Trac ticket.
Simon
The code below behaves well if compiled without optimisations (~36K maximum residency). When compiled with optimisations (-O1 or -O2, no discernible difference), it gets stuck in the infinite loop "always (return ())" [no surprise], but it runs in small space (+RTS -M58K for me). With -O2 -fno-state-hack (or -O1 -fno-state-hack), it leaks memory: 469,292,260 bytes allocated in the heap 837,326,332 bytes copied during GC 233,727,956 bytes maximum residency (9 sample(s)) 3,740,036 bytes maximum slop 456 MB total memory in use (4 MB lost due to fragmentation) --------------------------------------------- module Main (main) where import Control.Concurrent {- always :: Monad m => m a -> m b always a = a >> always a -} always :: Monad m => m a -> m b always a = do _ <- a always a spawner :: IO () spawner = always $ do forkIO $ always (return ()) putStrLn "Delaying" threadDelay 1000000 main :: IO () main = do putStrLn "Spawning" forkIO spawner putStrLn "Delaying main" threadDelay 4000000 -------------------------------------------